jUnit – What is Mocking ?

Before you start reading about mocking ,if you are not familiar with jUnit then have look at this post – jUnit – Unit testing overview to take basic understanding. Then come back here to get familiar with Mocking.

Mocking is creating objects that simulate the behavior of real objects.Mocking is one technique to allow testing of a unit of code with out being reliant upon dependencies

An object under test may have dependencies on other (complex) objects. To isolate the behavior of the object you want to test, you replace the other dependent objects by mocks that simulate the behavior of the real objects. This is useful if the real objects are impractical to incorporate into the unit test.

Lets say,  you have StudentService.java  unit of code which you want to write test cas

public class StudentService {

private StudentDao studentDao;

public void setStudentDao(StudentDao studentDao) {
this.studentDao = studentDao;
}

public String getGrade(int studentID) throws Exception {
Integer percentage = this.studentDao.getPercentage(studentID);
String grade = null;

if(percentage == null) {
throw new Exception("Unable to retrieve student percentage");
}

if(percentage > 90) {
return "A";
} else  if(percentage <=90 && percentage > 80) {
return "B";
} else if(percentage <=80 && percentage > 70) {
return "C";
} else if(percentage <=70 && percentage > 60) {
return "C";
} else {
return "D";
}
}
}

This unit of code depend on StudentDao.getPercentage which gets percentage of student from database by passing studentID.Based on percentage,service returns grade.

If you have decided to write test case then you will face following problems :

  1. This unit test is slow, because you need to start a database in order to get data from DAO.
  2. This unit test is not isolated, it always depends on external resources like database.
  3. This unit test can’t ensures the test condition is always the same, the data in the database may vary in time.
  4. This unit test needs setup of test data such that it covers all the possible scenarios including exception edge case.
  5. It’s too much work to test a simple method, cause developers skipping the test.

Don’t worry solution is Mocking. There are many frameworks available and we will use Mokito framework to mock the object.

We need to simulate StudentDao.getPercentage method by mocking StudentDao. This way SudentService will not depend on StudentDao to retrieve data from database. Mocking will allow to simulate getPercentage  method to return mock data based on input parameter.

public class StudentServiceTest {

private StudentService studentService = new StudentService();

private StudentDao studentDao;

@Before
public void setUpForEachTestcase() {
this.studentDao = Mockito.mock(StudentDao.class);
this.studentService.setStudentDao(studentDao);
}

public void testGetGradeOfStudentHavingAGrade() throws Exception {
Mockito.when(studentDao.getPercentage(100)).thenReturn(99);

String grade = this.studentService.getGrade(100);

Assert.assertEquals("A", grade);
}

public void testGetGradeOfStudentHavingDGrade() throws Exception {
Mockito.when(studentDao.getPercentage(101)).thenReturn(50);

String grade = this.studentService.getGrade(50);

Assert.assertEquals("D", grade);
}

public void testGetGradeThrowExpcetionOfGradeRetrieval() throws Exception {
Mockito.when(studentDao.getPercentage(101)).thenReturn(null);
String grade = null;
try {
grade = this.studentService.getGrade(50);
} catch (Exception e) {
Assert.assertNull(grade);
Assert.assertEquals("Unable to retrieve student percentage", e.getMessage());
}

}

}

 

This test case creates mock of StudentDao before running each test case.

this.studentDao = Mockito.mock(StudentDao.class);

Simulate method getPercentage which tells test case that when getPercentage  is called with input parameter 100 then it should return 99%.

Mockito.when(studentDao.getPercentage(100)).thenReturn(99);

This way we can simulate StudentDao class to test behavior of real object StudentService. You don’t have to worry about what StudentDao actually performs as it is actually not calling it and mock it to return the data.

Done. If you enjoyed this post, I’d be very grateful if you’d help it spread by emailing it to a friend, or sharing it on social media. Thank you!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s