How to mock a dependency using JMockit?

In today’s post I would talk about mocking dependencies using JMockit. To write clean and complete unit test cases we have to mock out the dependencies.

The complete source code of this blog can be cloned from github

Steps involved in mocking a dependency using JMockit

  1. Mock the dependency reference using @Injectable
  2. Create a NonStrictExpectations exepecation for the method/behavior to be mocked.
  3. Verify that NonStrictExpectations created for the mocked object is invoked. Use Verifications to verify the invocations.

In the below given example the ShoutingManger has an UglyWordService. To test the shout behavior of the ShoutingManger we don’t need real UglyWordService. So we mocked UglyWordService using the JMockit @Injectable annotation.

package com.ourownjava.tdd.mockit;
/**
*
* @author Sanju Thomas
*
*/
public class ShoutingManager {
private UglyWordService uglyWordService;
public String shout(){
return uglyWordService.getAnUglyWord();
}
}
package com.ourownjava.tdd.mockit;
import java.util.Random;
public class UglyWordService {
private static String [] uglyWords = new String [] {"@#$#$", "F@#$#@$", "S@#$#$", "@#$#$#24", "@#$#$^#!@#"};
public String getAnUglyWord() {
return uglyWords[randomNumber()];
}
private int randomNumber() {
return new Random().nextInt((4 — 0) + 1) + 0;
}
}
package com.ourownjava.tdd.jmockit;
import static org.junit.Assert.assertTrue;
import java.util.Arrays;
import java.util.Random;
import mockit.Deencapsulation;
import mockit.Injectable;
import mockit.NonStrictExpectations;
import mockit.Verifications;
import org.junit.Before;
import org.junit.Test;
import com.ourownjava.tdd.mockit.ShoutingManager;
import com.ourownjava.tdd.mockit.UglyWordService;
/**
*
* @author Sanju Thomas
*
*/
public class TestShoutingManager {
private String [] goodWords = new String [] {"You are so nice", "This is an excellent test case",
"Good work", "We had an excellent release", "You work really hard"};
private ShoutingManager shoutingManger;
//using @Injectable annotation we are mocking the UglyWordService
@Injectable
private UglyWordService uglyWordService;
@Before
public void setUp(){
shoutingManger = new ShoutingManager();
//now we are injecting the mocked UglyWordService to shoutingManger instance
Deencapsulation.setField(shoutingManger, "uglyWordService", uglyWordService);
}
//we are now testing the shout behavior of the shouting manger
//we are smart developers, we mocked shouting manager's UglyWordService
//and wired a mocked UglyWordService into shoutingManager object.
@Test
public void shouldShout(){
new NonStrictExpectations(){{
uglyWordService.getAnUglyWord();
returns(goodWords[randomNumber()]);
}};
final String word = shoutingManger.shout();
assertTrue(Arrays.asList(goodWords).contains(word));
new Verifications() {{
uglyWordService.getAnUglyWord();
}};
}
private int randomNumber(){
return new Random().nextInt((4 — 0) + 1) + 0;
}
}