Tag Archives: ios

How to test services that make async network calls in Swift and return an Optional

One of the things that threw me the first time I did iOS development was the fact network calls were done asynchronously by default. From an implementation side this was nice, I didn’t have to worry about blocking my main thread. But from a testing side… well that was something new.

Since then Apple’s come out with Swift. And with Swift comes the need to learn new ways to do things.  A couple of things I wanted to work out how to do nicely was:  how can I stub out my network layer as I don’t want my test to have to run against a dummy backend, and secondly how can I assert the Optional value I get back is set.

Turns out it wasn’t too tricky. The optional var was set as a result of an async call, so the easiest way to check the value is to first wait till the var has a non nil value.

And stubbing out the network layer was easily achieved by using OHHTTPStubs.

My final test ended up looking like:

 

Adventures with Swift and unit testing

Firstly, it’s been a long time with no blog. Life, the universe kind of caught up with me. That and I think blogging for a number of years in my late teens/early twenties kind of got the better of me… But from now on, let’s see how this blogging stuff goes. Hopefully it’ll be a place for me to brain dump my thoughts and learnings… Which brings me onto the topic of this post ‘Adventures with Swift and unit testing’.

Bit of background, about 5 years ago in my previous job I was part of an ios development team. Things were different back then. Where I worked didn’t practice TDD and the testing landscape was fairly immature with respect to mobile development.

Fast forward to the present and I work at place that does TDD and tooling/frameworks for testing ios development has vastly improved. It’s still somewhat behind what I’m used to as a Java developer, but we need to bear in mind the mobile ecosystem/environment is still relatively new in the timeframe of things (the first iPhone was only released in 2007).

At WWDC 2014 Swift was introduced. I’ve read a bit here and there, but I’m finally getting round to giving it a try – TDD style. With Xcode 6 beta 4 access controls has been introduced which has provided a bit of an interesting situation with unit testing.

Access controls come in 3 flavours:

  • Public – as it states, accessible from it’s own module as well as any other code that imports the said module. Pretty much more or less the same as public in Java.
  • Internal – Only accessible within the defined module. Somewhat similar to package private in Java.
  • Private – Only accessible via the defining source code. Pretty much the same as private in Java.

What’s interesting is that by following good practices of encapsulation using the above access levels brings about some interesting implications for unit testing. This comes about because in ios developer a test target is not part of the applications module and thus cannot see anything that is not marked public. This is particularly frustrating as in Java something marked package private can still be accessed/seen in the test tree when in the same package.

The beta release notes actually state:

Can this be worked around? Somewhat so… At the moment you could mark everything as public, but that seems rather unfortunate as it pretty much bypasses any encapsulation. Add the class under test to your unit test target.

Interestingly enough, on the developer forums Chris Lattner has posted that they know the access control design doesn’t really work for unit testing…