android Clean Code — Part 1

Mohanraj Karatadipalayam
6 min readMay 23, 2017

Test Driven App Development in Android

This blog is about my journey of finding the right mobile app unit testing framework and how I arrived at Clean Code Android, a design pattern. When you finish this blog series, I promise, you will learn how to unit test your mobile app, piece by piece.

Let us start with Unit Testing

Writing an android app that has good unit test code coverage is not easy, as the android code has a massive activity class that manages more than one function or tasks. Typical activity class do the below tasks

  • Data retrieval from data sources like API, local database or a content provider
  • Data manipulation and decoration of the retrieved data according to UI needs
  • UI Specific activities like rendering, painting, responding to user events and creation of fragments

When you try to accomplish more than one tasks in a single class, often the Activity or Fragment grows to be massive class and its methods are intertwined and do everything, everywhere. Testing the methods in this setup is not easy, you need to have too many dependencies that need to be mocked. Maintaining the test code with many mocks takes a lot of effort.On search of a perfect unit test tools like JUnit, Robolectric, android instrumentation, we often overlook app development architecture adaptability for unit testing.

One of the major reasons behind the failure of the unit test automation is an architecture of the app that does not support unit testing.

It is important to have a development architecture that supports testing and uses minimal mocking or no mocking at all. When your app development architecture does not support the unit testing inherently, the testing framework cannot lift you from the soup you have created for yourself.

Knowing that we need a good design pattern that aids testing, Uncle Bob’s clean-architecture as the reference guide, i have started searching for the design patterns suitable for test driven development in mobile apps.

Uncle Bob’s Clean Code Architecture

Native Mobile Development Patterns

Out of numerous design patterns that are created for mobile app development, one closely resembles clean code architecture and popular in the iOS world is VIPER.

Plain vanilla implementation of VIPER in iOS have its own challenges. There is no configurator in Uncle Bob’s Clean Architecture or VIPER (which does all the setup in the app delegate), results in code littered by doing extraneous setup code. clean-swift is an iOS pattern that overcomes these challenges, where the wiring of the dependencies was extracted to the configurator.

If the words like VIPER, configurator sounds new to you, don’t worry, continue reading, you will understand it later.

Wait a minute, we are discussing Android design patterns and the suggestion is to use a iOS design pattern.

Why not?

Android and iOS development are very similar when removing the ingenuity of each platform, with clean-swift design pattern we will be able to test at least 80% of the code.

Force fitting a VIPER into Android have its sets of problems, you can read more about in Lyubomir blog. In Android Clean Code, which is adopted from clean-swift, the issues mentioned in the Lyubomir blog were taken care of, trust me and read on.

Android Clean Code

Welcome to this world, Android Clean Code, build from clean-swift.It is built on the principle of SOLID.

Clean Android is built by splitting the monolithic activity into several units.

A) Every activity needs to get the data from one or more data source, data retrieval work will be handled by interactor class.
B) Once the data is retrieved by the interactor, the data may need to be modified in the form that can be presented by the activity, the class which does this work is the presenter.
C) Activity does the regular work of presenting the data and accepting the user actions in form of events.

How the activity, interactor, and presenter talk to each other?

Classes talking to each other using interfaces

Using the interfaces.

When the screen needs to be loaded, it calls Interactor using the InteractorInput interface to fetch the data.

Once data retrieval is successful or failure, Interactor calls Presenter using the PresentorInput interface to decorate the raw data.

Once the data is in presentable form, Presenter calls Activity using ActivityInput interface to present the data. As you see the data flow is unidirectional.

Why we use interfaces?
Classes talks to each other using the interfaces, during the unit testing, we will be able to mock the other classes without much of a sweat.

Let’s get started

Clone the example project and open it in Android Studio

Activity

When designing the activity class, we must determine what activity class should do and what it should not.

Keeping the SRP principle, the work of the activity is to present the data to the user and listen to the user actions, nothing more, nothing less.

For the activity to present the data, it needs data from data sources, should it get the data by itself?

No, it should delegate the work to Interactor by using the interfaces. Let us define the interface

We define a member in the Activity class that will hold the implementation instance of the interface.In the onCreate method of the Activity, call the method that will retrieve the data for activity.

Wait a minute, how the output member will be initialized with proper implementation?

Configurator does the wiring of the dependencies, more on that later, if you use the cleanAndroid-code-generator, these classes will be autogenerated for you.

Let us focus on the testing, write a test case to test the Activity, you can refer code here. We will use robolectric instead of JUnit to test the activity as robolectric does the heavy lifting of mocking the Android ecosystem like context.

We will write a simple test case to see if the Activity is created. I call this as Canary test, to see basic pieces were wired properly.

Now we know the activity is indeed created, let us check if the Interactor method is called, how do we test the activity without Interactor?

You should be able to test without actual Interactor, let us use a spy to check if the method is called.

Want to understand what is the spy, mock, stubs? Check here.

Let us create the spy for the interface HomeInteractorInput.

The code is self-explanatory, it implements the interface and needed methods of the interface. Also as a spy, it records the input and set the member to record the method is called.

Let us create the test method to test Interactor is called.

Let us also test if the interactor method is called with right input.

Though we are unit testing a class that has simple logic, you may understand how powerful is this design pattern, which enables the developer to test whether the method is called and values of the parameters that are passed. In fact, the developer can unit test the activity class piece by piece.

Before we close this exercise, run the test cases with code coverage (Android Studio → Menu →Run →Run with coverage) and see yourself how much is the Activity class is covered.

What’s next?

Interactor in the next post.

————————————————— — — — — — — — — — — — — — — —

Acknowledgments

--

--

Mohanraj Karatadipalayam

Polyglot developer, Engineering manager for iOS and Android apps, Amadeus Labs