-
Notifications
You must be signed in to change notification settings - Fork 11
Home
Request Matcher is a library for making it quite simple to test Android applications that communicate with a server. As stated in the README, there are several approaches to doing so:
- Dependency Injection: have two different configurations of your dependencies container. One for your real app and another for your tests. In your tests you implement the interactions as not making any real call but just making the necessary assertions and returning the expected behaviour for your tests.
- Evil API: have a test implementation of your API contracts. That is similiar with the dependency injection approach but without any framework required. Some libraries such as Retrofit provide some facilities to go this route with retrofit-mock dependency.
- Mocking libraries: use of mocking libraries such as Mockito, PowerMock and etc. This injects a different instance of your server interaction component and configures an expected return per call.
Those are all valid strategies that really do work. Each of them has their respective advantages and disadvantages but in the end they all work.
We believe that an arguably better approach is to avoid having test specific implementations. Specifically what we are trying to avoid is mocks of your code. When you need to mock your own code to properly test it there is something not right. Mocks (or test specific implementations) should be used for external dependencies and should not pollute your call stack. If you are testing a product list and you mock your fetching products layer, you skip a very important part of your call stack in your test. If possible it would be preferable to let it try and hit some place that would always answer with the expected test result such as an empty list, a complete list, a 400 response and what not. We should have the same call stack for our tests that our production application will have, right?
Another bad thing to avoid is tons of test code. Setting up proper mocks for test should be the dumbest code ever or else you'll start wondering about testing your test code. If there are plenty of if
s in your test setup then you really SHOULD think about creating tests for that.
But wait! There is an alternative. I haven't mentioned MockWebServer
. This is the OkHttp implementation of a mocked web server that has the ability to enqueue mocked responses. It is a real server that has a scheme, a host, a port and so on. So, the only thing we need now is to point our application to hit this mocked web server and enqueue our expectations in our test method. Wonderful :)
And indeed it is nice. The only thing is that this does not come with assertions out of the box. That is, if you want to be sure your app is generating the proper requests, you have to assert that with your own assertions after the server interactions are done. This is not very convenient. Another issue is that you may enqueue as many responses as you would like. There is no guarantee that they were all used. You have to check that manually. This falls in our second "things to avoid" category. Our tests should not have plenty of code in it.
So here comes RequestMatcher
. This library is a wrapper around MockWebServer
that provides some utilities:
- Assertions happen during request processing and not after. We provide a fluent interface assertion mechanism that we will explore in length below.
- All enqueued responses MUST be used or else the test will fail. There won't be left overs.
- A fixture mechanism to load mocked response bodies.
- This comes with implementations for both tests that run on the JVM (like Robolectric tests) and instrumented tests (like Espresso or Robotium).
The result is that your test must only point to the RequestMatcherRule
server. After that, you can start enqueuing responses that have fixtures as their body and make assertions on the fly.