Android Clean Code — Part 3
Having understood how to test the Android Activity and Interactor in earlier blogs of the series, let’s look at the Presenter and its testing.
What is the work of Presenter?
A) To change the data retrieved from Interactor according to the UI needs. Typically you may want to decorate the data or derive a value from the set of data fetched by Interactor ( For example, the total number of future trips in the list of the trips that contains both future and past trips).
B) Filter data, when needed.
C) Sort the data (default sorting),when needed.
In this example, we use Presenter for decoration.
Date of travel is in the YYYY/MM/DD format when passed from Interactor, we need to show a message showing the days to departure if the trip is in future.
If it is a past trip, show a message with the days since the departure.
Let’s look at the Presenter
Presenter implements the PresenterInput
interface. In this class, method presentHomeMetaData
takes care of data decoration. It creates the view model from the model that is passed by the Interactor and passes it to the Activity to display the data. Most of the data is copied without any change to the view model from the model, except noOfDaysToFly
, where the private method setDaysFlyDecorationText
does the calculation of the days to fly, based on the current date.
Once the view model is created, Presenter calls the Activity using the ActivityInput Interface.
The class member
output
of typeActivityInput
is aWeakReference
so that we don’t create circular references. These members were wired by Configurator which will be explained in a future post, if you use the cleanAndroid-code-generator, these classes will be autogenerated for you.
If you look at the code again, you will be able to understand the logic, it is straight forward.
Unit Testing
Let’s look at the unit testing the code, we will start with the test to verify whether the Activity is called with right inputs.
Should we need Activity class to test the presenter?
No, we should use the mock of Activity. Let us create the Mock first
Let us create a test method to verify if the displayHomeMetaData is called with right inputs
Now knowing that the next class in the unidirectional data flow is called as expected, let us test the decoration logic — present the number of days to fly instead of the date of travel.
One of the FIRST principles in writing successful test cases is that the test should be repeatable.
The value for
viewModel.noOfDaysToFly
is calculated based on the current date, the value forviewModel.noOfDaysToFly
can change depending upon the time of unit test execution. We overcome that by setting the current time as (2017-May-30) in the test code and make the test performing consistently.
We use the object ActivityInputSpy to verify the values of the view model.
Like the above example, we can test the each and every public method of the presenter. By this time, you may have realised how powerful is Android Clean Code design pattern — it helps you unit test the app piece by piece, without hardwiring dependencies. Check the complete Presenter test class here.
I suggest you clone the example project, if not done already and before we close this exercise, run the test cases with code coverage(Android Studio → Menu →Run →Run with coverage). Check the code coverage of the Presenter class.
What’s next? We’ll talk about Router in the next post.