Mockito – easily test your application

http://www.i-net-design.com/2012/04/20/mockito-easily-test-your-application/

Who didn’t know that? As developer you have to test your application with some unit tests, but how
to test a service which uses a session object for example.

Now we can easily mock this object to test our function successfully.

As example I use very small code snippets to show you how to use Mockito.

First of all the service to test:

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
@Component public class MyClass{
@Autowired
private SessionFacadeService sessionFacadeService;
/**
* @return
*/
public List<STRING> myMethod(){
List result = new ArrayList<STRING>();
if ( sessionFacadeService != null ){
String language = getLanguageKey();
// The rest of the method // ... }
return result;
}
/**
* Here's our session needed
* @return
*/
public String getLanguageKey()
{
return sessionFacadeService.resolveHttpSession().getAttribute( "languageKey" );
}
public void setSessionFacadeService( SessionFacadeService sessionFacadeService )
{
this.sessionFacadeService = sessionFacadeService;
}
}

As we can see, the method ‘getLanguageKey()’ needs a sessionService, this service
resolves the actual session which hold the languageKey.

Therefore we need to mock the sessionService, otherwise a successful test is impossible
because in test environment we don’t have a session.

Here we go, create a test method:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class MyClassTest{
/**
* Here's the test
*/
@Test
public void testMyMethod()
{
// MyClass myClass = new MyClass();
//Set up the rest of your test ...
// The test call List<STRING> myList = myClass.myMethod();
// Here you test the call with assert ...
}
}

This test will fail because there’s no session object available which is used by the session service.

We’ll have to mock the session service to avoid the call of ‘resolveHttpSession()’.

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
@RunWith( MockitoJUnitRunner.class ) public class MyClassTest{
private SessionFacadeService mockSessionFacadeService()
{
SessionFacadeService sessionFacadeService = Mockito.mock( SessionFacadeService.class );
HttpSession session = Mockito.mock( HttpSession.class );
Mockito.when( sessionFacadeService.resolveHttpSession() ).thenReturn( session );
return sessionFacadeService;
}
/**
* Here's the test
*/
@Test
public void testMyMethod()
{
// MyClass myClass = new MyClass();
//Set the mocked service. myClass.setSessionFacadeService( this.mockSessionFacadeService() );
//Set up the rest of your test ...
// The test call List<STRING> myList = myClass.myMethod();
// Here you test the call with assert ...
}
}

This test will also fail, we mocked out the sessionService, but a mock is like an empty object.
Therefore we set a mocked session into the service, but this session don’t contains a language key.

So we just mock away the whole function call of ‘getLanguageKey()’ and just return the result.
So we need another feature of Mockito – we use the ‘spy()’ method:

Here’s the improved test method which successfully ends up:

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
36
37
38
39
@RunWith( MockitoJUnitRunner.class ) public class MyClassTest{
private SessionFacadeService mockSessionFacadeService()
{
SessionFacadeService sessionFacadeService = Mockito.mock( SessionFacadeService.class );
HttpSession session = Mockito.mock( HttpSession.class );
Mockito.when( sessionFacadeService.resolveHttpSession() ).thenReturn( session );
return sessionFacadeService;
}
/**
* Here's the test
*/
@Test
public void testMyMethod()
{
// MyClass myClass = new MyClass();
MyClass spyMyClass = Mockito.spy(myClass);
// This return directly a String value instead performing a function call Mockito.doReturn( "en_US" ).when( spyMyClass ).getLanguageKey();
//Set the mocked service. spyMyClass.setSessionFacadeService( this.mockSessionFacadeService() );
//Set up the rest of your test ...
// The test call List<STRING> myList = spyMyClass.myMethod();
// Here you test the call with assert ...
}
}

But be careful, there’s also another feature in Mockito which is used instead of ‘doReturn()’.

1
2
Mockito.doReturn( "en_US" ).when( spyMyClass ).getLanguageKey();
Mockito.when( spyMyClass.getLanguageKey() ).thenReturn( "en_US" );

Mockito.doReturn() return the necessary result immediately on function call.
Mockito.when() runs into the function and only change the return value.

So if we want to test with all function, we use Mockito.when(), if we want to test only the necessary
function without sub function calls, we use Mockito.doReturn().

Hope I could show you how to use Mockito with this little example.

More information are available at the Mockito website: http://code.google.com/p/mockito/