Sign In Start Free Trial
Account

Add to playlist

Create a Playlist

Modal Close icon
You need to login to use this feature.
  • Book Overview & Buying Mockito Essentials
  • Table Of Contents Toc
Mockito Essentials

Mockito Essentials

By : Sujoy Acharya
4 (4)
close
close
Mockito Essentials

Mockito Essentials

4 (4)
By: Sujoy 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 (9 chapters)
close
close

Exploring a test spy

A spy secretly obtains the information of a rival or someone very important. As the name suggests, a spy object spies on a real object. A spy is a variation of a stub, but instead of only setting the expectation, a spy records the method calls made to the collaborator. A spy can act as an indirect output of the unit under test and can also act as an audit log.

We'll create a spy object and examine its behavior; the following are the steps to create a spy object:

  1. Launch Eclipse, open <work_space>, and go to the 3605OS_TestDoubles project.
  2. Create a com.packt.testdoubles.spy package and create 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);
      }
    
    }

    The StudentService class contains a map of the course names and students. The enrollToCourse method looks up the map; if no student is enrolled, then it creates a collection of students, adds the student to the collection, and puts the collection back in the map. If a student has previously enrolled for the course, then the map already contains a Student collection. So, it just adds the new student to the collection.students list.

  3. The enrollToCourse method is a void method and doesn't return a response. To verify that the enrollToCourse method was invoked with a specific set of parameters, we can create a spy object. The service will write to the spy log, and the spy will act as an indirect output for verification. Create a spy object to register method invocations. The following code gives the method invocation details:
    class MethodInvocation {
    
      private List<Object> params = new ArrayList<>();
      private Object returnedValue = null;
      private String method;
    
      public List<Object> getParams() {
        return params;
      }
    
      public MethodInvocation addParam(Object parm){
        getParams().add(parm);
        return this;
      }
    
      public Object getReturnedValue() {
        return returnedValue;
      }
    
      public MethodInvocation setReturnedValue(Object returnedValue) {
        this.returnedValue = returnedValue;
        return this;
      }
    
      public String getMethod() {
        return method;
      }
    
      public MethodInvocation setMethod(String method) {
       this.method = method;
        return this;
      }
    }

    The MethodInvocation class represents a method invocation: the method name, a parameter list, and a return value. Suppose a sum() method is invoked with two numbers and the method returns the sum of two numbers, then the MethodInvocation class will contain a method name as sum, a parameter list that will include the two numbers, and a return value that will contain the sum of the two numbers.

    Note

    Note that the setter methods return this(MethodInvocation). This coding approach is known as builder pattern. It helps to build an object in multiple steps. Java StringBuilder is an example of such a use:

    StringBuilder builder = new StringBuilder();
    builder.append("step1").append("step2")…

    The following is the spy object snippet. It has a registerCall method to log a method call instance. It has a map of strings and a List<MethodInvocation> method. If a method is invoked 10 times, then the map will contain the method name and a list of 10 MethodInvocation objects. The spy object provides an invocation method that accepts a method name and returns the method invocation count from the invocationMap class:

    public class StudentServiceSpy {
      private Map<String, List<MethodInvocation>> invocationMap = new HashMap<>();
    
      void registerCall(MethodInvocation invocation) {
        List<MethodInvocation> list = invocationMap.get(invocation.getMethod());
        if (list == null) {
          list = new ArrayList<>();
        }
        if (!list.contains(invocation)) {
          list.add(invocation);
        }
    
        invocationMap.put(invocation.getMethod(), list);
      }
    
      public int invocation(String methodName){
        List<MethodInvocation> list = invocationMap.get(methodName);
        if(list == null){
          return 0;
        }
    
        return list.size();
      }
    
      public MethodInvocation arguments(String methodName, int invocationIndex){
        List<MethodInvocation> list = invocationMap.get(methodName);
        if(list == null || (invocationIndex > list.size())){
          return null;
        }
        return list.get(invocationIndex-1);
      }
    }

    The registerCall method takes a MethodInvocation object and puts it in a map.

  4. Modify the StudentService class to set a spy and log every method invocation to the spy object:
      private StudentServiceSpy spy;
      public void setSpy(StudentServiceSpy spy) {
        this.spy = spy;
      }
      public void enrollToCourse(String courseName, Student student) {
        MethodInvocation invocation = new MethodInvocation();
        invocation.addParam(courseName).addParam(student).setMethod("enrollToCourse");
        spy.registerCall(invocation);
    
        List<Student> list = studentCouseMap.get(courseName);
        if (list == null) {
          list = new ArrayList<>();
        }
        if (!list.contains(student)) {
          list.add(student);
        }
    
        studentCouseMap.put(courseName, list);
      }
  5. Write a test to examine the method invocation and arguments. The following JUnit test uses the spy object and verifies the method invocation:
    public class StudentServiceTest {
      StudentService service = new StudentService();
      StudentServiceSpy spy = new StudentServiceSpy();
    
      @Test
      public void enrolls_students() throws Exception {
        //create student objects
        Student bob = new Student("001", "Robert Anthony");
        Student roy = new Student("002", "Roy Noon");
        //set spy
        service.setSpy(spy);
    
        //enroll Bob and Roy
        service.enrollToCourse("english", bob);
        service.enrollToCourse("history", roy);
        //assert that the method was invoked twice
        assertEquals(2, spy.invocation("enrollToCourse"));
    
        //get the method arguments for the first call
        List<Object> methodArguments = spy.arguments
    ("enrollToCourse", 1).getParams();
    
        //get the method arguments for the 2nd call
        List<Object> methodArguments2 = spy.arguments
    ("enrollToCourse", 2).getParams();
    
        //verify that Bob was enrolled to English first
        assertEquals("english", methodArguments.get(0));
        assertEquals(bob, methodArguments.get(1));
    
        //verify that Roy was enrolled to history
        assertEquals("history", methodArguments2.get(0));
       assertEquals(roy, methodArguments2.get(1));
    
      }
    
    }
CONTINUE READING
83
Tech Concepts
36
Programming languages
73
Tech Tools
Icon Unlimited access to the largest independent learning library in tech of over 8,000 expert-authored tech books and videos.
Icon Innovative learning tools, including AI book assistants, code context explainers, and text-to-speech.
Icon 50+ new titles added per month and exclusive early access to books as they are being written.
Mockito Essentials
notes
bookmark Notes and Bookmarks search Search in title playlist Add to playlist font-size Font size

Change the font size

margin-width Margin width

Change margin width

day-mode Day/Sepia/Night Modes

Change background colour

Close icon Search
Country selected

Close icon Your notes and bookmarks

Confirmation

Modal Close icon
claim successful

Buy this book with your credits?

Modal Close icon
Are you sure you want to buy this book with one of your credits?
Close
YES, BUY

Submit Your Feedback

Modal Close icon
Modal Close icon
Modal Close icon