Book Image

Mockito Essentials

By : Acharya
Book Image

Mockito Essentials

By: Acharya

Overview of this book

This book is ideal for developers who have some experience in Java application development as well as some basic knowledge of test doubles and JUnit testing. This book also introduces you to the fundamentals of JUnit testing, test doubles, refactoring legacy code, and writing JUnit tests for GWT and web services.
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.