Over a million developers have joined DZone.

Android Clean Code : Part 1

DZone 's Guide to

Android Clean Code : Part 1

On your search for the perfect mobile unit testing tool, it's important not to overlook your app's architecture and whether it supports unit testing.

· Mobile Zone ·
Free Resource

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's Start With Unit Testing

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

  • Data retrieval from data sources like API, a 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 the creation of fragments.

When you try to accomplish more than one task in a single class, often the Activity or Fragment grows to be a massive class and its methods are intertwined and do everything, everywhere. Testing the methods in this setup is not easy; you have too many dependencies that need to be mocked. Maintaining the test code with many mocks takes a lot of effort. In the search for 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 app architecture 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, with 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.

Image title

Uncle Bob's Clean Code Architecture.

Native Mobile Development Patterns

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

Plain vanilla implementation of VIPER in iOS has its own challenges. There is no configurator in Uncle Bob’s Clean Architecture or VIPER (which does all the setup in the app delegate), resulting in code littered by 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 words like VIPER and configurator sound new to you, don’t worry and continue reading; you will understand later.

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

Why not?

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

Force-fitting a VIPER into Android has its problems; you can read more about on the 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 the world of 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.

  • Every activity needs to get the data from one or more data source; data retrieval work will be handled by interactor class. 

  • 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.

  • Activity does the regular work of presenting the data and accepting the user actions in form of events.

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

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 fails, Interactor calls Presenter using the PresentorInput interface to decorate the raw data.

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

Let’s get started. Clone the example project and open it in Android Studio


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

Keeping the SRP principle, the work of the activity class 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.

interface HomeInteractorInput {
    public void fetchHomeMetaData(HomeRequest request);

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.

public class HomeActivity extends AppCompatActivity implements HomeActivityInput {
    protected HomeInteractorInput output;

    protected void onCreate(Bundle savedInstanceState) {


    public void fetchMetaData() {
        // create Request and set the needed input
        HomeRequest homeRequest = new HomeRequest();
        homeRequest.isFutureTrips = true;
        // Call the output to fetch the data

Wait a minute, how will the output member 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 was created. I call this a Canary test, to see if basic pieces were wired properly.

public void HomeActivity_ShouldNOT_be_Null(){
    HomeActivity activity = Robolectric.setupActivity(HomeActivity.class);

    // Then

Now that 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 the actual Interactor; let us use a spy to check if the method is called.

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

Let us create the spy for the interface HomeInteractorInput.

private class HomeActivityOutputSpy implements HomeInteractorInput {

        boolean fetchHomeMetaDataIsCalled = false;
        HomeRequest homeRequestCopy;
        public void fetchHomeMetaData(HomeRequest request) {
            fetchHomeMetaDataIsCalled = true;
            homeRequestCopy = request;

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

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

    public void onCreate_shouldCall_fetchHomeMetaData(){
        HomeActivityOutputSpy homeActivityOutputSpy = new HomeActivityOutputSpy();
        HomeActivity homeActivity = Robolectric.setupActivity(HomeActivity.class);
        // It must have called the onCreate earlier,
        // we are injecting the mock and calling the fetchMetaData to test our condition
        homeActivity.output = homeActivityOutputSpy;



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

    public void onCreate_Calls_fetchHomeMetaData_withCorrectData(){
        HomeActivityOutputSpy homeActivityOutputSpy = new HomeActivityOutputSpy();
        HomeActivity homeActivity = Robolectric.setupActivity(HomeActivity.class);
        homeActivity.output = homeActivityOutputSpy;



Though we are unit testing a class that has simple logic, you may understand how powerful this design pattern is, as it 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 for yourself how much the Activity class is covered.

What’s next? We'll talk about Interactor in the next post.

clean architecture ,clean code ,unit testing ,automation testing ,mobile ,mobile testing

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}