Develop tips -mock

Many times during development, you may need to Mock a background for one of two reasons:

  • The background is not finished, only documents, front-end development and need data to facilitate development
  • Testing needs, our unit tests need all kinds of situations, many of which we can’t provide in the background under normal circumstances, and obviously we shouldn’t submit all kinds of test data to the real background.

So we provide different solutions for the above two different needs

For ease of development

I personally think it’s better not to write any code about mocks in your project, and I recommend two solutions, both of which require very little code about mocks in your project and just change the server address in your project.

Postman

Postman is a very popular tool to simulate requests, I believe you are familiar with him. The postman solution has the advantage of a UI page, which is more intuitive to operate

First we click the New button in the upper left corner

Then select the Mock Server

Then follow the prompts step by step, set the path, set the response content and some other content

If you need to modify the returned content after setting, please refer to the picture below and click the button in the upper right corner to modify it

moco

Moco is a Java backend, and once it’s downloaded and installed, you can write a JSON-formatted file with a single command

Change your app host address to localhost: and get the JSON data you wrote earlier

java -jar pathto/Moco-runner-<version>-standalone.jar http -p 12306 -c pathTo/foo.json

Note that if global flip wall is enabled, you need to change it to Auto Proxy mode; otherwise, the request will fail

In order to test

In the case of unit testing, although the scheme mentioned above can actually complete the test, it still needs to rely on the environment setting outside the project, which is not so perfect. It is then necessary to write the code in the project to complete the test independently of the environment outside the project

The correct word here is Stub

Let’s say we use the XCTest that comes with Apple

Since the network request is asynchronous, the unit test needs to use the XCTestExpectation waitForExpectations fullfile to complete the test. This section is no longer verbose and we will get straight to the point

We need the help of a third party library OHHTTPStubs

The library basically intercepts your request and returns what you specify, which could be a JSON file you wrote

We set up stubs first. We intercept requests for urls whose last part is “listItems” and return the contents of the httpstub.json file. There are other things you can set up here, such as blocking all requests to a Host, which you can set up in the OHHTTPStubs repository demo

- (void)installStubs { [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest * _Nonnull request) { return [request.URL.lastPathComponent isEqualToString:@"listItems"];  } withStubResponse:^OHHTTPStubsResponse * _Nonnull(NSURLRequest * _Nonnull request) { return [[OHHTTPStubsResponse responseWithFileAtPath:OHPathForFile(@"httpStub.json", self.class) statusCode:200 headers:@{@"Content-Type":@"application/json; Charset = utf-8 "}] requestTime: 0.5 f responseTime: OHHTTPStubsDownloadSpeedWifi];}]; }Copy the code

This method needs to be configured before the test actually starts, so we call installStubs in the setUp method

- (void)setUp {
    // Put setup code here. This method is called before the invocation of each test method in the class.
    [self installStubs];
}
Copy the code

Our command+U test returns the contents of our JSON file. This completes the simulated data part of the test

conclusion

There are three ways in this article, but I personally like the last one the best. Why?

First of all, it can completely replace the previous two methods, and does not rely on the network or third-party software. Although it intrudes into the project, fortunately, it is not very much. IF DEBUG can be used to ensure that the release version will not be affected even IF we forget to remove it.

Third, in order to do this was basically completed the interface of network request unit test cases, and can kill two birds with one stone, although the iOS development in this area, the test is not so popular, it is generally not do the job, but the test is an important way to ensure the quality of the project, get into the habit of writing test cases can help us find a lot of bugs in advance.

The resources

moco

Postman Setting up a mock serve

Real-World Testing with XCTest

The complete guide to Network Unit Testing in Swift

Asynchronous Tests and Expectations

isKindOfClass doesn’t work as expected

The concepts of Fakes, Mocks and Stubs were clear in the test