package lab.slices; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import java.math.BigDecimal; import java.time.LocalDate; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest; import org.springframework.context.ApplicationContext; import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.web.servlet.MockMvc; /** @WebMvcTest: the web layer only. BookService is replaced by a Mockito mock. */ @WebMvcTest(BookController.class) class WebMvcSliceTest { @Autowired MockMvc mvc; @Autowired ApplicationContext ctx; @MockitoBean BookService service; @Test void returnsABookAsJson_usingTheJacksonComponentAndTheControllerAdvice() throws Exception { given(service.get(1L)).willReturn( new Book("9780134685991", "Effective Java", "Joshua Bloch", new BigDecimal("499"), LocalDate.of(2018, 1, 6))); given(service.get(99L)).willThrow(new BookNotFoundException(99L)); String ok = mvc.perform(get("/api/books/1")) .andExpect(status().isOk()) .andExpect(jsonPath("$.title").value("Effective Java")) .andExpect(jsonPath("$.price").value("INR 499.00")) .andExpect(jsonPath("$.published_on").value("2018-01-06")) .andReturn().getResponse().getContentAsString(); String missing = mvc.perform(get("/api/books/99")) .andExpect(status().isNotFound()) .andExpect(jsonPath("$.title").value("Book not found")) .andReturn().getResponse().getContentAsString(); Transcript t = new Transcript("01-webmvc-slice.txt") .line("@WebMvcTest(BookController.class) with @MockitoBean BookService") .line("") .line("GET /api/books/1 -> 200 %s", ok) .line("GET /api/books/99 -> 404 %s", missing) .line("") .line("beans in this context:"); BeanProbe.record("WebMvcTest", ctx).forEach(l -> t.line(" %s", l)); t.write(); assertThat(ctx.getBeanNamesForType(BookService.class)).as("the mock is the only BookService").hasSize(1); assertThat(ctx.getBeanNamesForType(BookRepository.class)).isEmpty(); assertThat(ctx.getBeanNamesForType(AuditLogger.class)).isEmpty(); } }