Here Iam testing my endpoint using WebMvcTest
, MockMvc
and mocking service using @MockBean
.
Without using the standaloneSetup
method , the below code runs fine.
public class MessageControllerTest {
@Nested
@WebMvcTest
class TestUsingMockServer {
@MockBean
MessageServiceImpl messageService;
@Autowired
MockMvc mockMvc;
@Test
public void test_to_return_id_with_message_json() throws Exception {
when(messageService.findById(anyLong())).thenAnswer(invocation -> new Message("Hello World", (Long) invocation.getArguments()[0], LocalDateTime.now()));
mockMvc.perform(get("/resources/messages/{id}", 3)
.contextPath("/resources")
.accept(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(result -> {
result.toString().contains("3");
result.toString().contains("Hello World");
});
}
@Test
public void test_to_get_the_name_passed() throws Exception {
when(messageService.getMessageByIdName(anyLong(), anyString())).thenAnswer(invocation -> new Message("Hello " + invocation.getArguments()[1],
(Long) invocation.getArguments()[0], LocalDateTime.now()));
mockMvc.perform(get("/resources/messages/{id}", 3)
.queryParam("name", "kaustubh")
.contextPath("/resources")
.accept(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(result -> {
result.toString().contains("3");
result.toString().contains("kaustubh");
});
}
}
}
TO avoid repetition when I added standaloneSetup
method , and ran the tests I get error which says MessageServiceImpl bean is not initialized (because of NullPointerException
)
public class MessageControllerTest {
@Nested
@WebMvcTest
class TestUsingMockServer {
@MockBean
MessageServiceImpl messageService;
@Autowired
MockMvc mockMvc;
@BeforeEach
public void setUp(){
mockMvc = standaloneSetup(new MessageController())
.defaultRequest(get("/")
.contextPath("/resources")
.accept(MediaType.APPLICATION_JSON)
).build();
}
@Test
public void test_to_return_id_with_message_json() throws Exception {
when(messageService.findById(anyLong())).thenAnswer(invocation -> new Message("Hello World", (Long) invocation.getArguments()[0], LocalDateTime.now()));
mockMvc.perform(get("/resources/messages/{id}",3))
.andDo(print())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(result -> {
result.toString().contains("3");
result.toString().contains("Hello World");
});
}
}
}
Giving the following error
Line 17 as menitoned , in the error , calls to MessageServiceImpl
@RestController
@RequestMapping("/messages")
public class MessageController {
@Autowired
MessageServiceImpl messageService;
@GetMapping(path = "/{id}")
public Message getMessageById(@PathVariable Long id) {
return messageService.findById(id); // LINE 17
}
@GetMapping(path = "/{id}", params = "name")
public Message getMessageByIdName(@PathVariable Long id, @RequestParam(value = "name", defaultValue = "ST") String name) {
return messageService.getMessageByIdName(id, name);
}
}
Is happening because the MockMvc
builder is setup before the service bean created?