Book Image

Mockito Essentials

By : Sujoy Acharya
Book Image

Mockito Essentials

By: Sujoy Acharya

Overview of this book

Table of Contents (14 chapters)

Getting started with mock objects


A mock object is a combination of a spy and a stub. It acts as an indirect output for a code under test, such as a spy, and can also stub methods to return values or throw exceptions, like a stub. A mock object fails a test if an expected method is not invoked or if the parameters of the method don't match.

The following steps demonstrate the test failure scenario:

  1. Launch Eclipse, open <work_space>, and go to the 3605OS_TestDoubles project.

  2. Create a com.packt.testdoubles.mock package and a StudentService class. This class will act as a course register service. The following is the code for the StudentService class:

    public class StudentService {
    
      private Map<String, List<Student>> studentCouseMap = new HashMap<>();
    
      public void enrollToCourse(String courseName,Student student){
        List<Student> list = studentCouseMap.get(courseName);
        if (list == null) {
          list = new ArrayList<>();
        }
    
        if (!list.contains(student)) {
          list.add(student);
        }
    
        studentCouseMap.put(courseName, list);
      }
    }
  3. Copy the StudentServiceSpy class and rename it as StudentServiceMockObject. Add a new method to verify the method invocations:

    public void verify(String methodName, int numberOfInvocation){
      int actual = invocation(methodName);
      if(actual != numberOfInvocation){
        throw new IllegalStateException(methodName+" was expected ["+numberOfInvocation+"] times but actuallyactaully invoked["+actual+"] times");
      }
    }
  4. Modify the StudentService code to set the mock object, as we did in the spy example:

    private StudentServiceMockObject mock;
    
    public void setMock(StudentServiceMockObject mock) {
      this.mock = mock;
    }
    public void enrollToCourse(String courseName,Student student){
      MethodInvocation invocation = new MethodInvocation();
    
      invocation.addParam(courseName).addParam(student).setMethod("enrollToCourse");
    
      mock.registerCall(invocation);
      …//existing code
    }
  5. Create a test to verify the method invocation:

    public class StudentServiceTest {
      StudentService service = new StudentService();
      StudentServiceMockObject mockObject = new StudentServiceMockObject();
    
      @Test
      public void enrolls_students() throws Exception {
        //create 2 students
        Student bob = new Student("001", "Robert Anthony");
        Student roy = new Student("002", "Roy Noon");
    
        //set mock/spy
        service.setMock(mockObject);
    
        //invoke method twice
        service.enrollToCourse("english", bob);
        service.enrollToCourse("history", roy);
    
        //assert that the method was invoked twice
        assertEquals(2, 
        mockObject.invocation("enrollToCourse"));
    
        //verify wrong information, that enrollToCourse was //invoked once, but actually it is invoked twice
        mockObject.verify("enrollToCourse", 1);
    
      }
    
    }
  6. Run the test; it will fail, and you will get a verification error. The following screenshot shows the JUnit failure output:

The Mockito framework provides an API for mocking objects. It uses proxy objects to verify the invocation and stub calls.