How to be a Mock-Star…😎
In this article we will go through the transformation of an ordinary Android developer into a 😎
MockStar😎. We will see how she was forced to write tests which made her use testing tools like
Mockito to make her life easier and then dive a little into the usage and implementation of
MockWebServer. The demo project for this article is available on github.
One fine day, an android developer was feeling pretty awesome in the morning. After spending many days and nights swimming in the ocean of unlimited classes, events and interfaces, she had finally mastered the
Rxify spell, the art of using
Dagger and implemented MVP on her project. Little did she know, what was the true reason behind recommendation of this architecture and all the cool stuff. It was not just distribution of responsibility but also the “thing” which she had managed to avoid almost all her career.
“Testing” — the unavoidable Beast!
Maximum test-coverage for the logic layer
It was only a week earlier when her Project Manager had asked her for the estimates in the sprint planning meeting. She had confidently estimated all the stories without knowing what was coming her way.
Finally, the time came for “The Team Meeting”. The meeting which changed her whole life! Team Lead told her that her
logic layer had to have as much test coverage as possible! She sat like this for the next 15 minutes :
She desperately started looking into various testing frameworks and found out the ultimate “potion” to her problems :
“Why Drink it?
Mockito is a mocking framework that tastes really good. It lets you write beautiful tests with a clean & simple API. Mockito doesn’t give you hangover because the tests are very readable and they produce clean verification errors.” — Mockito.org
She quickly went through the documentation and started on the journey of writing tests. Everything was going great! She was properly Mocking out the views and creating Stubs. While trying to master the art of “when-then”, she had already started dreaming of the
Testing the Happy Paths of Presenter with Mockito
We have used the cute pokemons API for demo purpose here : pokeapi.
So, she was trying to test the
Presenter as shown in the gist below :
She wrote the test for the above code using
Mockito. She mocked out her
View and PokeDataSource. Have a look at the test for the above code :
After the above
when-then blah blah… we test if
setApiText() is called
1 time and
showErrorDialog() is called
0 times. Kindly note that, what actual data is shown, it’s not tested here as it’s not the responsibility of this test case for Presenter. That responsibility lies with our
Everything was going good, nice and smooth so far. She similarly went on to write the tests for the other cases and finally finished writing the test cases for other
Presenters in her logic layer. She ran code coverage tasks and BOOM! Not Enough Code-Coverage!
Well! That’s Sad. Now she will need to write more tests. She gets back to work and starts writing tests for some error conditions now.
Testing Error cases with Mockito
Now she wanted to test the following embarrassingly ugly
Big Deal? She confidently started to test the above cases by returning the appropriate
HttpException instance. Let’s see the code she wrote :
MediaType.parse("God Knows What?"),
"Why am I even alive?")))));
“It was not just enough to be able to write the logic tests and use all those cool tools, we have to have maximum test coverage for the logic layer” — She cried in her head.
After a long session of cursing-the-world due to the above “incident”, she got back to work with a cup of tea and clear mind. Then suddenly! it struck her that her whole life has been a lie. She didn’t really have to “Create” an
HttpException when she had
Mockito . She modified her test as follows :
AWESOME! She was able to test all the error cases just like the above. Have a look at her Presenter Test here. She again got a feeling of excitement that this might be the end of all testing-madness finally. She crossed her fingers and ran the
AND! BAM! Again “Not Enough Code Coverage! OH GOD WHY
She checked the test report and found out that
0 lines of coverage. Ohhhhh! She still had to test her
Testing the DataRepository
Next morning, she started testing her DataRepository which had the following public API
She again began Mocking stuff and by now she had started to almost hate the word
Mock itself. She would do anything to not use the
Now that we are testing the data source, we need to have some sort of mock data that should be provided here, to be able to test the
DataRepository properly. We could continue using
Mockito and write something like :
Main issue with the
PokemonService is the creation of Mock Response. The method
getMockPokemonResponse() is the main culprit.
It would have still been manageable if she was testing for only
pokemon.getId(). In order to be able to test the functionality properly, she had to feed it all sorts of not-so-cute values of
Pokemon. Have a look at the complexity of the above response here.
She knew that she had to do something better or easier at least. This brings us to the most interesting chapter of her journey towards becoming a Mock Star 😎.
It has a web server which runs on localhost and can be used to mock responses while testing our applications.
MockWebServer’s documentation and watching a few episodes of CasterIO videos on MockWebServer by Chiu-Ki Chan, She finally could see it clearly in her head. Her
MockStar title wasn’t too far-fetched now. Let’s see what got into her and how she took the road less travelled and implemented
MockWebServer to simplify the dull and monotonous task of writing tests.
Integrate MockWebServer in your app
She created a separate java module called
mocks where she would store the responses statically in
json format. She named the files in the format :
requestMethod_requestPath.json with all the
/ replaced by
GET pokemon/12 would be converted into :
She wrote a
Dispatcher to map the requests to their json files as follows and returned a
MockResponse object with response code
200 OK :)
With this and plugging-in the
MockWebServer in her repository by creating a test-dependency on the
testCompile project(':mocks'), she was able to get the tests up and running. With the help of
Dagger2 and it’s supercool advantage of being able to inject dependencies specific to our tests, she was able to setup
MockWebServer for her unit-tests in no-time. Let’s see how she converted the earlier tests to use
MockWebServer. She changed the Mockito
@Mock PokemonService to
Testing the DataRepository using MockWebServer
She wanted to again test the following call inside
She just invoked
pokemonService.getPokemon() within her unit-tests and
MockWebServer took care of the rest with it’s
MockResponse. Have a look at the
BaseLogicTest.java file here for more details.
No need to create any
DemoPokemonResponse just write the logic for your tests and you are good to go! After seeing the magic of
MockWebServer she went all nuts!!
Now, was the time to test the dreaded
SocketTimeoutException. I think we are really blessed to have
Dagger2 in our lives which makes it so easy to configure tests. Just change your
OkHttpClient configuration to
builder.readTimeout(2, SECONDS); and see the magic of
throttleBody() function, also explained in this video. You can find this test and others such as testing for correct Headers using
RecordedRequest here. For full code sample and setup, checkout this
mockstar repository on Github.
ANNNNNNND You are done!
Let’s run the
She finally finished her stories even before her “extended-deadline” and took that time to read some more articles on Medium *cough* facebook *cough*.
Any ordinary android developer can become a
MockStar by using all the right tools and by experience. There’s not just a single way of improving any code we write and I am not comparing
MockWebserver here, they both are extremely advantageous on their own. I think they can be used in conjunction, using the one where it’s needed. We can use
Mockito wherever we do not require actual data and just want to test the conditional flow. And
MockWebServer would come into picture where we need at least some data to be able to test something. Here, I have just covered how we can slightly “speed-up” the boring-but-yet-so-helpful task of writing unit tests in MVP.
I am just an ordinary developer myself — “a wannabe MockStar”, if you feel that there’s a better way, I would like to hear it. Also, the article is just a made up slightly related to the daily lives of developers like us. Let’s all improve and learn together. Kindly click the tiny heart button if you enjoyed this article.
Thank you for Reading :)