Recently I have come across a Mockito mocking framework for writing unit test cases. I found it simple to use and have written test cases for my android project. Finally decided to share information, let me start with what is need to start writing unit test cases in Android via Mockito. There will be two parts of the series where in first article I will be giving an introduction to the framework and how to set up Mockito.

In Second article, I will be discussing more on code perspective and Mockito API.

Mockito:-

  • Mockito is open source testing framework.
  • It is released under MIT License.
  • Mockito allows creation of mock objects in automated unit tests for the purpose of Test-driven Development (TDD) or Behavior Driven Development.

How it works

Unit test case written normally runs on developer local JVM. Gradle plugin will compile the source code found in src/test/java and execute it. At runtime, test cases will be executed against the modified version of android.jar where all final modifiers have been stripped off.

How to Setup in Android Studio

  • To start working with Android Studio, you need to include dependencies in your build.gradle file of your android module.
1
2
3
4
dependencies {
 testCompile 'junit:junit:4.12'
  testCompile "org.mockito:mockito-core:1.9.5"
}
  • Select “Unit Test” in Test Artifact under build variants.

mockito-setup

The android.jar file that is used to run unit tests does not contain any actual code – that is provided by the Android system image on real devices. Instead, all methods throw exceptions (by default). This is to make sure your unit tests only test your code and do not depend on any particular behaviour of the Android platform. If that proves problematic, you can add the snippet below to your build.gradle to change this behavior:

1
2
3
4
5
6
android {
  // ...
  testOptions { 
    unitTests.returnDefaultValues = true
  }
}

Deep down into few Mockito API’s:-

Before writing unit test straight away, let us cover few mockito api’s that will be useful in writing unit test.

Verify

1
2
3
4
5
6
7
8
// mocking of List class
List mockedList = Mockito.mock(List.class);
// stubbing values
mockedList.add("one");
mockedList.clear();
//verification
Mockito.verify(mockedList).add("one");
Mockito.verify(mockedList).clear();

Stubbing

1
2
3
4
5
6
//You can mock concrete classes, not only interfaces LinkedList
mockedList = mock(LinkedList.class);
//stubbing
when(mockedList.get(0)).thenReturn("first"); 
//stubbing Exception
when(mockedList.get(1)).thenThrow(new RuntimeException());
      • By default, for all methods that return value, mock returns null, an empty collection or appropriate primitive/primitive wrapper value (e.g: 0, false, … for int/Integer, boolean/Boolean, …).
      • Stubbing can be overridden: for example common stubbing can go to fixture setup but the test methods can override it.
      • Once stubbed, the method will always return stubbed value regardless of how many times it is called.
      • Last stubbing is more important – when you stubbed the same method with the same arguments many times.

Spying on real objects

      • You can create spies of real objects. When you use the spy then the real methods are called (unless a method was stubbed).
      • Spying on real objects is often associated with “partial mocking” concept. However, Mockito spies are not partial mocks. Mockito spy is meant to help testing other classes – not the spy itself. Therefore spy will not help if you intend to verify if method calls other method on the same object.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
List list = new LinkedList(); 
List spy = spy(list);
//optionally, you can stub out some methods:
when(spy.size()).thenReturn(100); 
//using the spy calls real methods 
spy.add("one");
//prints "one" - the first element of a list
spy.add("two");
System.out.println(spy.get(0));
//size() method was stubbed - 100 is printed 
System.out.println(spy.size());
//optionally, you can verify 
verify(spy).add("one"); 
verify(spy).add("two");

Important gotcha on spying real objects!

      • Sometimes it’s impossible to use when(Object) for stubbing spies. Example:
1
2
3
4
5
6
List list = new LinkedList();
List spy = spy(list);
//Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty) 
when(spy.get(0)).thenReturn("foo");
//You have to use doReturn() for stubbing 
doReturn("foo").when(spy).get(0);

Mocking static methods

Quick summary

  • Use the @RunWith(PowerMockRunner.class) annotation at the class-level of the test case.
  • Use the @PrepareForTest(ClassThatContainsStaticMethod.class) annotation at the class-level of the test case.
  • Use PowerMock.mockStatic(ClassThatContainsStaticMethod.class) to mock all methods of this class.

Few Limitations with Mockito:-

  • Can’t mock private methods.
  • Can’t mock static methods.
  • Can’t mock final methods or classes.

How to write test cases for above shortcomings:-

  • PowerMock is the answer of the above limitations we have.
  • PowerMock enables the mocking of static methods, constructor, private methods, and final classes.
1
2
3
4
5
6
7
@RunWith(PowerMockRunner.class)
@PrepareForTest(StaticClass.class)
public class MockStaticTest {
@TEST
public void testAnyStaticMethod(){
}
}

Lets see our next article, where we will be describing and writing test cases for different scenarios.

References

Leave a Reply

Your email address will not be published.