Android Clean Code — Part 4 — Router
Learn more about the Clean Code Android mobile design pattern and unit testing your Android app piece by piece for code quality.
Having understood how to test the Android Activity, Interactor and Presenter in Part 1, Part 2 and Part 3 of this series, let’s look at the Router and its testing.
Should we handle the next Activity determination logic in Activity class?
No, we should move it separate class - Router, respecting single responsibility principle (SRP).
What is the work of Router?
A) Determine the next screen
B) Pass the data need for the next screen
Typically these logic are handled by Activity class. Is it possible to unit test such logic in Activity class?
No, you have too many objects to mock — we are moving them to Router — so that we can test the logic, piece by piece.
In this example, if the trip date is in past, the Router should start the next Activity with the intent of PastTripActivity
, if the date is in current or Future, the Router should start the next Activity with the intent of BoardingActivity
.
Let’s look at Router
HomeRouter
implements the interfaces HomeRouterInput
and AdapterView.OnItemClickListener
.
The class member
activity
of typeActivity
is aWeakReference
so that we don’t create circular references. These members were wired by Configurator which will be explained in a future post.
android-clean-code-generator generates these classes, which will be explained in a future post.
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 if the date is in Future, the method determineNextActivity
should return the intent of BoardingActivity
.
Should we need Activity class to test the router?
No, we should use the mock of Activity. We are using Robolectric.setUpActivity
to create the mock.
Note that the unit test execution can happen at any date and we are setting the travel date as 2017/12/31. As we determine our logic based on dates, it is important for unit testing, we should the current date fixed, so that the test execution is consistent irrespective of the date of unit test execution.(see Repeatable in FIRST principle of unit testing). We have a method called setCurrentDate
created just to facilitate the testing.
Ohh, wait a minute ? are you creating a method in production code, just to facilitate the testing.
Yes, having a method that helps unit testing is always better that than no unit testing and living with the nondeterministic behavior of your app.
Like the above example, we can test the each and every public method of the Router. 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 Router 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 Router class.
What’s next? We’ll talk about Configurator and code scaffolding in the next post.
Thanks for reading this article. Be sure to click ❤ below to recommend this article if you found it helpful. It means a lot to me.