Mock NWPathMonitor to test iOS app functionality across varying network states
NWPathMonitor probably the easiest way to monitor network connectivity in an iOS Application. In this article I will show you how you can use it to track network connectivity changes and take necessary actions accordingly in your app and most importantly how you can write unit tests to verify scenarios such as connected internet and disconnected internet.
According to Apple's documentation NWPathMonitor is an observer that you can use to monitor and react to network changes. I created a simple SwiftUI app that has a single view that will show text based on network connectivity. If internet is connected it will show text "CONNECTED.." and if internet is disconnected it will show text "DISCONNECTED..".
Setting up initial code base
Create an Enum NetworkStatus for setting network status in ViewModel that will be used in View too:
Declare a protocol named NetworkPathMonitorProtocol to manage and mock network status.
Here, pathUpdateHandler will be used to provide network status to the ViewModel. func start(..) will be used to start the monitoring and func cancel() will be used to cancel the monitoring.
Create a class to implement the protocol which will be used from the ViewModel.
Now from ViewModel we will start the network monitor and listen the observer for network status. I used Global Queue, but custom queue is also a good option.
Code in the View struct is very simple like this:
领英推荐
Now the app is ready, if you run it and change network connectivity of your physical device (avoid simulator as it doesn't provide accurate output all the time) you can see text based on the connection status.
Writing unit test
In unit test we can't control the devices network connection to verify the behaviour of our app. So we have to create a mock class that will provide dummy network status. Let's create a mock class using the protocol NetworkPathMonitorProtocol that we already defined.
In this mock class we didn't create an instance of NWPathMonitor. We can easily set mock network status using currentNetworkStatus variable and use that to test our ViewModel behaviour.
Test setup will be look like this image. We will initiate the ViewModel using the object of the mock class MockNetworkPathMonitor.
Now we are ready to write unit tests. Unit test for connected state will look like below:
Here we set currentNetworkStatus = .satisfied as we want to test the ViewModel for connected state. dropFirst() is needed to discard the initial network status.
Similarly we can test for disconnected state by setting currentNetworkStatus = .unsatisfied:
You can find the demo project here: https://github.com/Shayokh144/iOSEssentials/tree/master/DemoApps/MockNWPathMonitor
Happy reading :)