In our previous article we had given a little introduction about Mockito.

Read our previous article first here, if don’t have any idea about how to use it in Android.

In this article I will show you, how to use it to write automated Unit test cases in Android.

API’s that has been written are very simple in nature.
For better understanding on the usage part I would like to explain little bit about code structure first.

In this project let’s assume I have written DataUtility class and other developer has written StoreData class. DataUtility class has dependency on StoredData class.
In technical terms “HAS-A” relationship.
Therefore, in order to write stand-alone unit test case for my DataUtility class I need to mock StoredData class.

This is the class for which I want to write test cases.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.example.arpit.samplemockito;
import android.content.Context;
import android.content.SharedPreferences;
 
public class DataUtility {
 
    private Context context;
    private StoredData storedData;
 
    public DataUtility(Context context){
        storedData = new StoredData();
        this.context = context;
    }
 
    public String reverseInputString(String input){
        return storedData.revereTheInputString(input);
    }
 
    public void storeCurrentTime(){
        SharedPreferences sharedPreferences = context.getSharedPreferences("Storage",Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putLong("CurrentTime", System.currentTimeMillis());
        editor.apply();
    }
 
    public long getStoredTime(){
        long storedTime = 0;
        SharedPreferences sharedPreferences = context.getSharedPreferences("Storage",Context.MODE_PRIVATE);
        if(sharedPreferences.contains("CurrentTime")){
            storedTime = sharedPreferences.getLong("CurrentTime",0l);
        }
        return storedTime;
    }
 
}

Let’s have a look at the test cases I have written.

1st Test Case:

Mocked the classes, which has dependency.
In this test case I have mocked StoredData class as DataUtility has dependency on its implementation.
I have set the internal state of the storedData variable in the DataUtility class via using WhiteBox.

1
2
3
4
5
6
7
    @Test
    public void reverseString_validInput_returnInput() {
        StoredData mockedStoredData = Mockito.mock(StoredData.class);
        Mockito.when(mockedStoredData.revereTheInputString(Mockito.anyString())).thenReturn("xyz");
        Whitebox.setInternalState(dataUtility, "storedData", mockedStoredData);
        Assert.assertEquals("xyz", dataUtility.reverseInputString("anyString"));
    }
2nd Test Case:

In this test case, I have mocked SharedPreference and its editor.I have used verify Api of Mockito to test if apply is called if storeCurrentTime is called.

1
2
3
4
5
6
7
8
9
    @Test
    public void storeCurrentTime_shouldStoreTime(){
        SharedPreferences mockedSharedPreference = Mockito.mock(SharedPreferences.class);
        Mockito.when(mockedContext.getSharedPreferences(Mockito.anyString(), Mockito.anyInt())).thenReturn(mockedSharedPreference);
        SharedPreferences.Editor mockedEditor = Mockito.mock(SharedPreferences.Editor.class);
        Mockito.when(mockedSharedPreference.edit()).thenReturn(mockedEditor);
        dataUtility.storeCurrentTime();
        Mockito.verify(mockedEditor).apply();
    }
3rd Test Case:

In this test case, I have mocked SharedPreference and stub true if contains Api of SharedPreference is called on the mocked object.

I have also Stub a long value on getLong Api, as soon it is called. It will always return me 122l.

1
2
3
4
5
6
7
8
    @Test
    public void getStoredTime_returnStoredTime(){
        SharedPreferences mockedSharedPreference = Mockito.mock(SharedPreferences.class);
        Mockito.when(mockedContext.getSharedPreferences(Mockito.anyString(), Mockito.anyInt())).thenReturn(mockedSharedPreference);
        Mockito.when(mockedSharedPreference.contains(Mockito.anyString())).thenReturn(true);
        Mockito.when(mockedSharedPreference.getLong(Mockito.anyString(), Mockito.anyLong())).thenReturn(122l);
        Assert.assertEquals(122l, dataUtility.getStoredTime());
    }
4th Test Case:

In this test case, I have mocked SharedPreference and stub false if contains Api of SharedPreference is called on the mocked object.

1
2
3
4
5
6
7
    @Test
    public void getStoredTime_timeIsNotStored_returnZero(){
        SharedPreferences mockedSharedPreference = Mockito.mock(SharedPreferences.class);
        Mockito.when(mockedContext.getSharedPreferences(Mockito.anyString(), Mockito.anyInt())).thenReturn(mockedSharedPreference);
        Mockito.when(mockedSharedPreference.contains(Mockito.anyString())).thenReturn(false);
        Assert.assertEquals(0,dataUtility.getStoredTime());
    }

I have only written few test cases for demonstration purpose.We can also refractor test cases further as we can easily see lots of redundant code in last three test cases.

It is simple and easy to use. It has many more Api which makes unit test case more simpler.Lets have a look here.

Complete code can be downloaded here.

4 comments on “Android Mockito Part – 2

  • Hi,

    Thank you for creating ‘easy to understand’ tutorial. I enjoyed it.
    I had some issue, please see below.
    I had similar test case like 2nd test case. But instead of long, I’m storing boolean.
    This test case was failing for me until I added following line before calling “dataUtility.storeCurrentTime()”
    Mockito.when(mockedEditor.putBoolean(Mockito.anyString(), Mockito.anyBoolean())).
    thenReturn(mockedEditor);

  • It was giving following error
    java.lang.NullPointerException
    at com.haggle.ecom.util.app.AppConfig.setUserVerified(AppConfig.java:25)
    at com.haggle.ecom.AppConfigTest.setUserVerified(AppConfigTest.java:37)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
    at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
    at org.junit.runners.Suite.runChild(Suite.java:128)
    at org.junit.runners.Suite.runChild(Suite.java:27)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

Leave a Reply

Your email address will not be published.