Skip to content

Mockito library

Yash edited this page Jan 23, 2022 · 2 revisions

Mockito logo Most popular Mocking framework for unit tests written in Java

Search / Ask question on stackoverflow

The Mockito library enables mock creation, verification and stubbing.

Main reference documentation features:

  • mock()/@Mock: create mock
    • optionally specify how it should behave via Answer/MockSettings
    • when()/given() to specify how a mock should behave
    • If the provided answers don’t fit your needs, write one yourself extending the Answer interface
  • spy()/@Spy: partial mocking, real methods are invoked but still can be verified and stubbed
  • @InjectMocks: automatically inject mocks/spies fields annotated with @Spy or @Mock
  • verify(): to check methods were called with given arguments
    • can use flexible argument matching, for example any expression via the any()
    • or capture what arguments were called using @Captor instead
  • Try Behavior-Driven development syntax with BDDMockito
  • Use Mockito on Android, thanks to the team working on dexmaker

discoversdk.com

DZONE « A mocked service replaces multiple dependencies


Click to expand! - Student,Course
public class Student {
  private String id;
  private String name;
  private String description;
  private List<Course> courses;
}
public class Course {
  private String id;
  private String name;
  private String description;
  private List<String> steps;
}
Click to expand! - StudentController
@RestController
public class StudentController {

  @Autowired
  private StudentService studentService;
  
  @GetMapping("/students/{studentId}/courses/{courseId}")
  public Course retrieveDetailsForCourse(@PathVariable String studentId, @PathVariable String courseId) {
    return studentService.retrieveCourse(studentId, courseId);
  }
  
  @PostMapping("/students/{studentId}/courses")
  public ResponseEntity<Void> registerStudentForCourse(@PathVariable String studentId, @RequestBody Course newCourse) {

    Course course = studentService.addCourse(studentId, newCourse);

    if (course == null) return ResponseEntity.noContent().build();

    URI location = ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(course.getId()).toUri();

    return ResponseEntity.created(location).build();
  }
}

Add spring-security-test for disabling security in unit tests

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-test</artifactId>
    <scope>test</scope>
</dependency>
Click to close! - StudentControllerTest
@RunWith(SpringRunner.class)
@WebMvcTest(value = StudentController.class)
@WithMockUser
public class StudentControllerTest {

  @Autowired
  private MockMvc mockMvc;

  @MockBean
  private StudentService studentService;

  Course mockCourse = new Course("Course1", "Spring", "10Steps",
      Arrays.asList("Learn Maven", "Import Project", "First Example", "Second Example"));

  String exampleCourseJson = "{\"name\":\"Spring\",\"description\":\"10Steps\",\"steps\":[\"Learn Maven\",\"Import Project\",\"First Example\",\"Second Example\"]}";

  @Test
  public void retrieveDetailsForCourse() throws Exception {

    Mockito.when( studentService.retrieveCourse(Mockito.anyString(), Mockito.anyString()) )
        .thenReturn(mockCourse);

    RequestBuilder requestBuilder = MockMvcRequestBuilders.get("/students/Student1/courses/Course1").accept(MediaType.APPLICATION_JSON);

    MvcResult result = mockMvc.perform(requestBuilder).andReturn();

    System.out.println(result.getResponse());
    String expected = "{id:Course1,name:Spring,description:10Steps}";

    // {"id":"Course1","name":"Spring","description":"10 Steps, 25 Examples and 10K Students","steps":["Learn Maven","Import Project","First Example","Second Example"]}

    JSONAssert.assertEquals(expected, result.getResponse().getContentAsString(), false);
  }

  @Test
  public void createStudentCourse() throws Exception {
    Course mockCourse = new Course("1", "Smallest Number", "1",
                 Arrays.asList("1", "2", "3", "4"));

    // studentService.addCourse to respond back with mockCourse
    Mockito.when(
        studentService.addCourse(Mockito.anyString(),
            Mockito.any(Course.class))).thenReturn(mockCourse);

    // Send course as body to /students/Student1/courses
    RequestBuilder requestBuilder = MockMvcRequestBuilders
        .post("/students/Student1/courses")
        .accept(MediaType.APPLICATION_JSON).content(exampleCourseJson)
        .contentType(MediaType.APPLICATION_JSON);

    MvcResult result = mockMvc.perform(requestBuilder).andReturn();

    MockHttpServletResponse response = result.getResponse();

    assertEquals(HttpStatus.CREATED.value(), response.getStatus());

    assertEquals("http://localhost/students/Student1/courses/1", response.getHeader(HttpHeaders.LOCATION));
  }
}
  • @RunWith(SpringRunner.class) : SpringRunner is short hand for SpringJUnit4ClassRunner which extends BlockJUnit4ClassRunner providing the functionality to launch a Spring TestContext Framework.
  • @WebMvcTest(value = StudentController.class): WebMvcTest annotation is used for unit testing Spring MVC application. This can be used when a test focuses only Spring MVC components. In this test, we want to launch only StudentController. All other controllers and mappings will not be launched when this unit test is executed.
  • @Autowired private MockMvc mockMvc: MockMvc is the main entry point for server-side Spring MVC test support. It allows us to execute requests against the test context.
  • @MockBean private StudentService studentService: MockBean is used to add mocks to a Spring ApplicationContext. A mock of studentService is created and auto-wired into the StudentController.
  • Mockito.when(studentService.retrieveCourse(Mockito.anyString(),Mockito.anyString())).thenReturn(mockCourse): Mocking the method retrieveCourse to return the specific mockCourse when invoked. Mockito.anyInt()
  • MockMvcRequestBuilders.get("/students/Student1/courses/Course1").accept(MediaType.APPLICATION_JSON): Creating a Request builder to be able to execute a get request to uri “/students/Student1/courses/Course1” with accept header as “application/json”
  • mockMvc.perform(requestBuilder).andReturn(): mockMvc is used to perform the request and return the response back.
  • JSONAssert.assertEquals(expected, result.getResponse().getContentAsString(), false): We are using org.skyscreamer.jsonassert.JSONAssert. This allows us to do partial asserts against a JSON String. We are passing strict as false since we do not want to check for all fields in the response.

Mockito Annotations

  • @Mock
  • @InjectMocks
  • @RunWith(MockitoJUnitRunner.class)
  • @Captor
@RunWith(MockitoJUnitRunner.class)
public class ListTest {

  //TodoService serviceMock = org.mockito.Mockito.mock( TodoService.class );
  @org.mockito.Mock
  TodoService serviceMock;
  
  //TodoBusinessService businessMock = new TodoBusinessService(serviceMock);
  @org.mockito.InjectMocks
  TodoBusinessService businessMock;
  
  //ArgumentCaptor<String> argumentCaptor = ArgumentCaptor.forClass(String.class);
  @org.mockito.Captor
  ArgumentCaptor<String> stringArgumentCaptor;
    
    @Test
    public void captureArgument() {
        ArgumentCaptor<String> argumentCaptor = ArgumentCaptor.forClass(String.class);
        List<String> allTodos = Arrays.asList("Learn Spring MVC", "Learn Spring", "Learn to Dance");
        assertEquals("Learn to Dance", argumentCaptor.getValue());
    }
}

Clone this wiki locally