Testing networking logic

Tram Ho

  • When consulting topic about unit testing or automated test we often come across very common terms like testable code like synchronous , predicable or always return the same output for different input . However in reality the net working code that we often come across is contrary to the terminology we encounter in topics.
  • Cause us difficulty test code net working is net working is inherently a work asynchronously and depends heavily on external factors such as internet connection , server , assorted operating systems different . The above factors all directly affect the performing , loading , and decoding of the net work request .
  • In this article we will focus on how to test asynchronous code snippets using the API Foundation :

1 / Verifying request generation logic:

  • When starting a new test implementation we should start the reverse by testing the accuracy of the most basic logic before moving on to test the API .
  • We will both instantiate the URLRequest from the Endpoint with some conditions attached. For testing to have common standards, we create EndpointKind without customizing:

  • We were able to write the suite test with the code above where we would need to correctly verify the URLRequest for the basic endpoint that don’t need HTTP header .

  • We will need to improve the test case above, we can get the wrong result because both the URLRequest we initialized as well as URL given URL can be nil (this is very unlikely but when write test case we should not leave out any uncertain cases).
  • Next we’re assuming that host will always be api.myapp.com , which go back to the fact that the app currently support we use net working enviroment as staging or production , moreover the app also has a few server with the host can address different.
  • We will have the first problem using XCTUnwrap to check if request are not initialized with nil . We should create typealias for special Endpoint :

  • To be able to control exactly how the host works, we use a dedicated URLHost to be able to wrap a simple String :

  • The benefit of using URLHost with specific type is that we can encapsulate common variations using static property in the enum like how to create property for the host like staging and production as well as default to dynamically handle it. Reason for app cases running in DEBUG mode :

  • We need to update more Endpoint method initialize URLRequest by enabling URLHost L:

  • To avoid having to manually handle each URL we use we need to improve URLHost to make it easier to initialize special URL with path like this:

  • The above code not only makes our test more tight, accurate as well as flexible. We can now make the test case easier to read and test.

  • We’ve spent quite a bit of effort writing custom APIs to improve our code base we can be more robust and flexible. We can create more test case to test Endpoint types quickly.

  • We should create some more test case test the real endpoint to make sure the code test working properly. In case we encounter an endpoint requires authentication , we will need to add an Authorization header when initiating the request :

2 / Using integration tests:

  • We are currently using the URLSession API in Foundation in conjunction with some Combine operator to build core net working code:

  • The successfully results of the above code not the ones we should be too concerned with because we use a series of custom system API that are controlled in some special way to make the test results pass. are often narrow and predictable.
  • Protocol is a method of improving test results not only in the above case but also for many other cases where we do not have to participate in customizing and controlling API . This is a useful and popular method, so in this article we will prioritize the other:
  • In Swift we see that URLSession uses URLProtcol to perform network tasks, the system Apple has provided as well as complete support for us to customize by using class . That means we can customize a HTTP Net working stack by ourselves without having to modify custom operator Combine before.
  • The downside of URLProtcol from my personal point of view is that it mainly relies on static method which means we will have to implement our mock separately. A temporary fix is ​​to use additional protocol MockURLResponser to allow us to create mock server return the necessary Data or Error :

  • The next thing we need is custom deploy more URLProtcol to override the method as follows:

  • We need URLSession to use mock protocol rather than using the default HTTP system. To do that we just need to let URLSession use MockURLProtocol but don’t forget to declare the initialization for URLProtcol itself:

  • With the above code we can now fixed the MockURLResponder protocol , for example we will refer to the encode following item :

  • We should consider using the synchronous logic that Combine introduced with using XCtTest to build synchronous logic rather than using the Grand Central Dispatch semaphore :

  • Like the Endpoint test of the system, we used a lot of effort to build useful tools to be able to deploy the test with more concise lines of code. We will conduct test successfully load and successfully load test the request as well as decode :

  • YEAHH !!!, The last thing we need to take care of is that we can confirm that the networking methods work as expected when errors occur:

Share the news now

Source : Viblo