How do I do unit tests for code using system objects?

That's probably a bad title, let's try with specifics: we have a network extension, it has some classes / functions of its own, and they, when push comes to build, depend on (for example) NEAppProxyFlow and its subclasses. The code is written in Swift, since it is the language of the future.

If I want to do a unit test for my code, I need to provide something that at least looks like NEAppProxyFlow, since I can't otherwise create one. I thought I could provide my own NetworkExtension module for test case, but that... did not work well, and I still don't understand why.

On the other hand, I'm really bad at making unit tests, so the odds that I'm missing something fairly obvious to most other people are pretty high.

Answered by DTS Engineer in 796422022
Matt Easton … said otherwise

Well, that kinda depends on your definition of “mock up a test object”. The thread that my colleagued linked to has itself a link to a more more detailed explanation of my advice on this topic.

If it were in ObjC, I could do #if and/or #define tricks to include different headers

Right. Some folks thing of this as a limitation of Swift, but personally I think it’s a good thing, because the structure it requires will server you well in the long term.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

For an answer to your question, see this thread: https://developer.apple.com/forums/thread/749579.

For additional information, watch 2018 WWDC Testing Tips & Tricks and read Updating your existing codebase to accommodate unit tests.

Matt Easton over at https://forums.developer.apple.com/forums/thread/756508 said otherwise -- specifically,

For example, your flow copying logic relies on NEAppProxyFlow objects, but you could mock up a test object that represents the infrastructure in this class to just pipe network traffic into it to exercise your flow copying logic.

If it were in ObjC, I could do #if and/or #define tricks to include different headers, but I don't know how I'd do that with Swift. (And I can never remember how to define something in build settings or the command line and have Swift able to use #if for it, so I always have to go searching for it again.)

Matt Easton … said otherwise

Well, that kinda depends on your definition of “mock up a test object”. The thread that my colleagued linked to has itself a link to a more more detailed explanation of my advice on this topic.

If it were in ObjC, I could do #if and/or #define tricks to include different headers

Right. Some folks thing of this as a limitation of Swift, but personally I think it’s a good thing, because the structure it requires will server you well in the long term.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Well, I can do the same thing in Swift, it just wasn't as obvious, by using #if and typealias appropriately. It's not much uglier than in C, so that's fine.

The goal is to test things like error states, open/close states, and various callbacks. So I mocked up my own NWHostEndpoint (aka TestNWHostEndpoint), NEAppProxyFlow, etc. They're immensely simplistic, and won't test as well as the real thing, but I should be able to test my API fairly well.

(This was all motivated by the fact that my attempt to use DispatchIO crashes, every time, with enough load, and I can't figure out why. So maybe if I mock up a couple hours' worth of 100+ flows/sec, I might be able to track it down.)

How do I do unit tests for code using system objects?
 
 
Q