Writing Unit Test on Android

Tuğçenur Erdoğan
Delivery Hero Tech Hub
8 min readDec 24, 2021

In this article, you will find the answers to the questions of what is the test, what are the types of tests, is it necessary, why should we write a unit test, how can we write a unit test, what are the unit test writing frameworks (Mockito, JUnit etc.), the technologies used and how they are used.

Test is a development-trial method used to try to give an expected result according to the specified inputs. Testing is an important part of software development, even if it’s underrated. By adding tests with your code, you can make sure that when new code is added, the application still works properly and that subsequent changes do not break the application. Upgrading quickly and catching bugs before they are released gives you peace of mind. Tests are divided into three different types: UI(User Interface) Tests, Integration Tests, Unit Tests.

The Testing Pyramid

UI Tests, as the name suggests, interact with the user interface of the app. They imitate the user behavior and assert UI results. Espresso is the most commonly used framework for UI testing on Android.

Integration Tests are used when it is necessary to control how the code interacts with other parts of the Android Framework.

Roboelectric is the most used framework for Integration testing on Android.

Unit Tests are used to test a specific unit. So, the system under test is one class and only focus on it. On Android, the most commonly used frameworks for unit testing are JUnit and Mockito.

The importance of tests is recognized as:

  • UI Test: 10%
  • Integration Test: 20%
  • Unit Test: 70%

Now we can talk about Unit Tests in detail, which is the main topic of the article and is the most important test for development.

Unit Test

Unit tests are the fastest and easiest tests to write and the quickest to run. We write unit tests if we want to ensure that a class or method is working as intended. There are different technologies used to write unit tests for Android projects. I would like to mention JUnit and Mockito which are the most used ones. And differences between JUnit and Mockito, and the differences between them.

JUnit

It is a unit testing library used for testing Java-based codes. JUnit is a framework and there are versions such as Juint 3, Junit 4, Junit 5.
We will be working with JUnit 4 version throughout this article. It contains annotations such as @Test, @Before, @After, etc. For example, JUnit 5 contains annotations such as @Test, @BeforeEach, @AfterEach, @BeforeAll, @AfterAll. Here we will be using only @Test annotation and make this project using the Kotlin language. And if you noticed @Test annotation is common in both versions.

JUnit tests follow a typical four phase sequence: setup, exercise, verify, teardown.

Now, I will show you how to write a simple unit test using JUnit tool.

To start unit testing your Android project using JUnit you need to add the JUnit dependency to your project and you need to create a test source-set which is going to contain the source code for the unit tests. By default, a project created with Android Studio contains the JUnit dependency and the test resource set. If not, you can add the following line of code to the dependencies in the build.gradle(Module) file.

4.13.2 is version number of JUnit Framework. But when you see this tutorial, maybe new version may have been released.

Let’s create a class where we do mathematical operations.

Then, let’s create a special Test class for this class by following the step below.

Step 1 — Generate a Test Class
Step 2 — Naming to class
This is the final state of the Test class

@Test annotation and assertEquals function are the auxiliary items we use. We define the test functions(testSum(), testSubtract() and testMultiple())using the @Test annotation. In other words, in the example, it is stated that the methods are test methods with @Test. Using the assertEquals() function, we check if the sum(), subtract(), and multiple() methods return the expected value. In short, the use of the JUnit library consists of using annotations.

Let’s focus one of methods and its test methods we wrote.

The defined subtract() method is a subtraction method. It performs the function of returning the value a-b as output using the two inputs a and b. The testSubtract() method, which was written to test this method, tests whether it can find the expected value of 3 when it gives 8 and 5 as input to the subtract() method. In other words, only one of the situations to be experienced is controlled. Thus, it is understood that the method works correctly in all other cases. Let’s test the subtract() method and see if it passes.

Last step: Run the Test

How to run the test class?

In this way, you can run all test methods at the same time, or you can test each method individually.

Showing that all methods passed the test according to the test result

If our methods did not pass the test, if the expected value and the value returned by the method were not equal, we would see the following test result:

This style of testing uses state verification. That is, by examining the state of the SUT(System Under Test) and its collaborators after the method is executed, you can determine if the executed method worked correctly. As we will see, mock objects allow different approaches to verification.

There is another type of verification called behavior verification. Here, we want the object under test to call a specific collaborator method. For example, you might have a repository object that retrieves data from the network, and you might call a collaborator object and store it in your database before returning a result. Again, you can use Mockito to monitor your collaborators and verify if specific methods were called on it.

In general, in this part, we learned how to write a unit test for a simple class using JUnit, one of the test frameworks. Now we will focus on writing unit tests with Mockito, another popular framework.

Mockito

Mockito is a popular open source framework for mocking objects in software test. Using Mockito makes it much easier to develop tests for classes with external dependencies. A mock object is a dummy implementation of an interface or class.This allows you to define the output of certain method calls. They usually record interactions with the system, and tests can confirm this. This allows for easier test setup.

Writing a unit test is sometimes not as easy as in the example above. Sometimes we may have to write a test for a method of a class that requires cooperation from another class. But, Unit Tests normally focus on a single class, so we should avoid using their real collaborators. Otherwise, we would be doing integration testing. One way to avoid using real collaborators is to write unit tests using the Mockito Framework. We can create fake collaborators using the mocking and stubbing techniques provided by the Mockito.

Mockito Tests follow a typical three phase sequence : stub, use, verify.

Workflow in Mockito

In recent versions of Mockito, you can also mock static methods. Also, private methods are not visible for tests and cannot be mocked. Mockito records the interaction with the mock so that you can see if the mock object was used correctly, for example, if a particular method was called in the mock. This allows you to implement behavioral tests rather than just testing the results of method calls.

Developing and modernizing Android architectures have now begun to be designed in a way that is most suitable for writing tests. While developing software with these architectures, we started to divide our codes into layers according to their functions and isolate them from each other (data, domain, presentation layer, etc.). Data flow needs to occur between these layers, which perform functions unaware of each other. This creates interdependencies between layers. Mocking usually comes into play at this point. In general, the objects we will mock are objects from these dependencies. We can list the reasons for this as follows.

  • Since we are testing a unit, it is ensured by mocking that the dependencies connected to this flow do not disturb the test flow while testing the flow there.
  • While performing unit testing, it allows us to direct the test in the scenario we want.
  • It allows us to get rid of the slowness of complex objects.
    The mocking process is applied to the other layers on which it is dependent for each layer while the unit test is being written. Mockito is among the most used libraries on the Android side in this process.

Now we can move on to the phase where we see the use of Mockito with a short example. Let’s make a small project written in MVP architecture and write a unit test for the Presenter class.

To start unit testing your Android project using Mockito you need to add the Mockito dependency to your project :

3.11.2 is version number of Mockito Framework. But when you see this tutorial, maybe new version may have been released. Don’t forget to check.

Let’s set up a project structure where we stream Whatsapp-style messages on the page. First we start with the data class.

Let’s create a data provider interface.

And let’s create the View interface where the views are held.

Finally, we can create Presenter class which is the last step before testing.

Now we will write a unit test for this MessagePresenter class. If you have noticed, there are dependencies, but at this point, we will be able to get rid of this situation with mocking.

There are different ways to enable the use of annotations with Mockito tests. Firstly, The first option we have is to MockitoJunitRunner with @RunWith annotation the whole test class. This is also used in the example above. Alternatively, we can enable Mockito annotations by invoking MockitoAnnotations.openMocks().

For example :

Secondly, we declare class-level mocks with @Mock annotation and lateinit var modifier. Thus, we created fake dependencies. Then, we configure DataProvider stub with Mockito.’when’().thenReturn() function. Finally, we execute system under test entry method with messagePresenter.getAll() and verify with Mockito that given elements were displayed on view with Mockito.verify() method.

I hope this article answers many questions such as what is Unit Test, how to write it, which frameworks we can use, what is JUnit, what is Mockito, what is mocking. See you in my next informative articles.

--

--