Guide to refactor and build robust android application with Testing
Why this blog post:
I’m currently refactoring, maintaining a 5–8 years project and to make this blog post short, I will just focus on one business requirement of the application.
When I started to work on this project the app was supposed to be designed using an MVP Architecture pattern, but even thought the design of this project was supposed to follow the MVP pattern, it’s seems that the previous maintainer did not really understand the pattern, which leads to presenter with methods like this and that’s not the scariest one:

For new developers in the project, hunting bugs, improving and refactoring this method would be difficult because of the complexity and readability of this method and even if we improve or change this method how do we know that we did not break something?
Many android developers don’t see the purpose of writing tests and think of it as a waste of time.
I strongly disagree, testing your application is very important to ensure the quality of the product and more.
Even if you’re working in an agency with outsourcing projects and client in a rush, I bet the delivery of high quality product or software application which requires lower maintenance cost and hence results into more accurate, consistent and reliable results is more important to your clients.
Also testing should be part of your journey to be a better android developer, so stop postponing it and JUST DO IT.
So that’s why I decided to write this blog post, so everybody can be better android developers.
1- Application architecture:
Application architecture is really important in order to write proper tests.No matter which architecture pattern you use, your code should follow SOLID principles.
Let’s digest the setCurrentVehicle method and refactor it.
So as we can see in the setCurrentVehicle we need a model (M of MVP) that can execute the business logic necessary to set the current vehicle and since this model is a dependency of this presenter, it’s should be moved to the constructor.
Also presenter should only have business logic required to present some information to the user and PLEASE don’t use android framework classes in presenters!

I named the model VehiclesRepository but it can be anything you want and it’s also an interface, so we can switch it with any implementation that suit our needs.
Next let see what this vehiclesRepository model should do:

So for what we can see here (well what you can see, I already know the business requirements), this model should stop the tracking of this vehicle, change the current vehicle in the database to the new selected vehicle and start tracking the new vehicle.
Stopping tracking of a vehicle is something related to remote service so let’s create a remote data source and a local data source to execute specific tasks.
So our vehiclesRepository constructor looks like this since it’s depending on these two data sources:

Now let’s implement this business logic here, if you are fan of clean architecture, you can think of the method in this repository as a use case.
I changed the setCurrentVehicle to updateCurrentVehicle because setCurrentVehicle method makes me think of a pojo property setter and pojo property setter should not have async work inside.

Don’t worry about the other tasks like resetActiveIntegrationState and changeNovehicleStatus, those are new business requirements.
Now the presenter setCurrentVehicle look like this:

Sorry for the strongly typed import, some legacy code in this presenter use RxJava 1 but don’t worry I’m already migrating it.
Now let’s test our changes.
2- Unit Tests:
Unit tests are the entry point for anyone new in testing.
So in most cases you would unit test the presenter, but in our case the presenter does not contain the business requirement so our unit test will be the implementation of our vehiclesRepository interface.

Since our implementation of VehiclesRepository has all his dependency provided by constructor we can easily mock them to change the behavior like we want and all dependencies provided for the implementation are interfaces:

Now in our setup method we will create mock of those dependencies:

Now let’s test one of our business logic, the business logic say if tracking of the previous vehicle could not be stop the current vehicle should not be changed.

3- UI Test
Now we need to test view reaction to presenter request, it’s kind of unit test, but for UI and UI error handling.
So in this project I have setup dagger and dagger offer you the possibility to override graph for test if your application architecture is properly setup.
Since our presenter only depends on the vehiclesRepository and don’t know about data sources, in a UI test we only have to mock the repository.
Here is the dagger module for production:

Now for testing, we only need the repository no data sources (it’s at the bottom):

as a simple example, we want to test that a specific error is shown if we could not change the vehicle.
First, we need a way to get our mocks from dagger graph, I have a special rule that extends activityRule and call the setup method before the activity is created and a test application who extends the real application and return me the fake dagger component with my dependencies, if you would like to know more about extending the espresso power with dagger, let me known in the comment section:

Now the test:

4- Integration test:
That’s too much for this blog post and i think it’s already clear.
What do we gain from all this:
1- If before pushing our code we run the tests locally, or in our CI (like Jenkins), we could easily know if any of our changes broke something.
2- We can easily refactor and be sure that everything work like it should.
3- We are more confident in the quality of the application, we submit to our clients.
There’s a lot more reason…
Thanks for reading, if you have any questions, please leave a comment below or contact me at: bitsydarel@gmail.com
My github account: https://github.com/bitsydarel
