Using JsonPath in MockMVC Test
BeerController
@RequestMapping("/api/v1/beer")
@RestController
public class BeerController {
private final BeerService beerService;
@GetMapping(path = {"/{beerId}"},produces = { "application/json" })
public ResponseEntity<BeerDto> getBeerById(@PathVariable("beerId") UUID beerId){
return new ResponseEntity<>(beerService.findBeerById(beerId), HttpStatus.OK);
}
}
BeerControllerTest
import static org.hamcrest.core.Is.is;
import static org.mockito.ArgumentMatchers.any;
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.*;
@ExtendWith(MockitoExtension.class)
class BeerControllerTest {
@Mock
BeerService beerService;
@InjectMocks
BeerController beerController;
MockMvc mockMvc;
BeerDto validBeer;
@BeforeEach
void setUp() {
validBeer = BeerDto.builder().id(UUID.randomUUID())
.version(1)
.beerName("Beer1")
.beerStyle(BeerStyleEnum.PALE_ALE)
.price(new BigDecimal("12.99"))
.quantityOnHand(4)
.upc(123456789012L)
.createdDate(OffsetDateTime.now())
.lastModifiedDate(OffsetDateTime.now())
.build();
mockMvc = MockMvcBuilders.standaloneSetup(beerController).build();
}
@Test
void testGetBeerById() throws Exception {
given(beerService.findBeerById(any())).willReturn(validBeer);
mockMvc.perform(get("/api/v1/beer/" + validBeer.getId()))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(jsonPath("$.id", is(validBeer.getId().toString())))
.andExpect(jsonPath("$.beerName", is("Beer1")));
}
}
Using JsonPath with List
BeerController
@RequestMapping("/api/v1/beer")
@RestController
public class BeerController {
private static final Integer DEFAULT_PAGE_NUMBER = 0;
private static final Integer DEFAULT_PAGE_SIZE = 25;
private final BeerService beerService;
public BeerController(BeerService beerService) {
this.beerService = beerService;
}
@GetMapping(produces = { "application/json" })
public ResponseEntity<BeerPagedList> listBeers(@RequestParam(value = "pageNumber", required = false) Integer pageNumber,
@RequestParam(value = "pageSize", required = false) Integer pageSize,
@RequestParam(value = "beerName", required = false) String beerName,
@RequestParam(value = "beerStyle", required = false) BeerStyleEnum beerStyle){
if (pageNumber == null || pageNumber < 0){
pageNumber = DEFAULT_PAGE_NUMBER;
}
if (pageSize == null || pageSize < 1) {
pageSize = DEFAULT_PAGE_SIZE;
}
BeerPagedList beerList = beerService.listBeers(beerName, beerStyle, PageRequest.of(pageNumber, pageSize));
return new ResponseEntity<>(beerList, HttpStatus.OK);
}
}
BeerControllerTest
@ExtendWith(MockitoExtension.class)
class BeerControllerTest {
@Mock
BeerService beerService;
@InjectMocks
BeerController beerController;
MockMvc mockMvc;
BeerDto validBeer;
@BeforeEach
void setUp() {
validBeer = BeerDto.builder().id(UUID.randomUUID())
.version(1)
.beerName("Beer1")
.beerStyle(BeerStyleEnum.PALE_ALE)
.price(new BigDecimal("12.99"))
.quantityOnHand(4)
.upc(123456789012L)
.createdDate(OffsetDateTime.now())
.lastModifiedDate(OffsetDateTime.now())
.build();
mockMvc = MockMvcBuilders.standaloneSetup(beerController).build();
}
@DisplayName("List Ops - ")
@Nested
public class TestListOperations {
@Captor
ArgumentCaptor<String> beerNameCaptor;
@Captor
ArgumentCaptor<BeerStyleEnum> beerStyleEnumCaptor;
@Captor
ArgumentCaptor<PageRequest> pageRequestCaptor;
BeerPagedList beerPagedList;
@BeforeEach
void setUp() {
List<BeerDto> beers = new ArrayList<>();
beers.add(validBeer);
beers.add(BeerDto.builder().id(UUID.randomUUID())
.version(1)
.beerName("Beer4")
.upc(123123123122L)
.beerStyle(BeerStyleEnum.PALE_ALE)
.price(new BigDecimal("12.99"))
.quantityOnHand(66)
.createdDate(OffsetDateTime.now())
.lastModifiedDate(OffsetDateTime.now())
.build());
beerPagedList = new BeerPagedList(beers, PageRequest.of(1, 1), 2L);
given(beerService.listBeers(beerNameCaptor.capture(),
beerStyleEnumCaptor.capture(),
pageRequestCaptor.capture())).willReturn(beerPagedList);
System.out.println(beerPagedList);
}
@DisplayName("Test list beers - no parameters")
@Test
void testListBeers() throws Exception {
mockMvc.perform(get("/api/v1/beer")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(jsonPath("$.content", hasSize(2)))
.andExpect(jsonPath("$.content[0].id", is(validBeer.getId().toString())));
}
}
}
Using Custom Message Converter with Spring MVC Test
BeerControllerTest
@ExtendWith(MockitoExtension.class)
class BeerControllerTest {
@Mock
BeerService beerService;
@InjectMocks
BeerController beerController;
MockMvc mockMvc;
BeerDto validBeer;
@BeforeEach
void setUp() {
validBeer = BeerDto.builder().id(UUID.randomUUID())
.version(1)
.beerName("Beer1")
.beerStyle(BeerStyleEnum.PALE_ALE)
.price(new BigDecimal("12.99"))
.quantityOnHand(4)
.upc(123456789012L)
.createdDate(OffsetDateTime.now())
.lastModifiedDate(OffsetDateTime.now())
.build();
mockMvc = MockMvcBuilders.standaloneSetup(beerController)
.setMessageConverters(jackson2HttpMessageConverter()) // Newly added
.build();
}
@Test
void testGetBeerById() throws Exception {
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ");
given(beerService.findBeerById(any())).willReturn(validBeer);
MvcResult result= mockMvc.perform(get("/api/v1/beer/" + validBeer.getId()))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(jsonPath("$.id", is(validBeer.getId().toString())))
.andExpect(jsonPath("$.beerName", is("Beer1")))
.andExpect(jsonPath("$.createdDate",
is(dateTimeFormatter.format(validBeer.getCreatedDate()))))
.andReturn();
System.out.println(result.getResponse().getContentAsString());
}
@DisplayName("List Ops - ")
@Nested
public class TestListOperations {
@Captor
ArgumentCaptor<String> beerNameCaptor;
@Captor
ArgumentCaptor<BeerStyleEnum> beerStyleEnumCaptor;
@Captor
ArgumentCaptor<PageRequest> pageRequestCaptor;
BeerPagedList beerPagedList;
@BeforeEach
void setUp() {
List<BeerDto> beers = new ArrayList<>();
beers.add(validBeer);
beers.add(BeerDto.builder().id(UUID.randomUUID())
.version(1)
.beerName("Beer4")
.upc(123123123122L)
.beerStyle(BeerStyleEnum.PALE_ALE)
.price(new BigDecimal("12.99"))
.quantityOnHand(66)
.createdDate(OffsetDateTime.now())
.lastModifiedDate(OffsetDateTime.now())
.build());
beerPagedList = new BeerPagedList(beers, PageRequest.of(1, 1), 2L);
given(beerService.listBeers(beerNameCaptor.capture(), beerStyleEnumCaptor.capture(),
pageRequestCaptor.capture())).willReturn(beerPagedList);
}
@DisplayName("Test list beers - no parameters")
@Test
void testListBeers() throws Exception {
mockMvc.perform(get("/api/v1/beer")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(jsonPath("$.content", hasSize(2)))
.andExpect(jsonPath("$.content[0].id", is(validBeer.getId().toString())));
}
}
// Coming up with a Customized implementation of the Jackson configuration
public MappingJackson2HttpMessageConverter jackson2HttpMessageConverter(){
ObjectMapper objectMapper = new ObjectMapper();
// Customizing the objectMapper to properly parse timestamps
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
objectMapper.configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, true);
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
objectMapper.registerModule(new JavaTimeModule());
return new MappingJackson2HttpMessageConverter(objectMapper);
}
}
@WebMvc Test Slice
Using Curated Message Converter with Spring Boot
// Sets up the WebMvcTest Slice
@WebMvcTest(BeerController.class)
class BeerControllerTest {
// Spring is going to inject it
@MockBean
BeerService beerService;
@Autowired
MockMvc mockMvc;
BeerDto validBeer;
@BeforeEach
void setUp() {
validBeer = BeerDto.builder().id(UUID.randomUUID())
.version(1)
.beerName("Beer1")
.beerStyle(BeerStyleEnum.PALE_ALE)
.price(new BigDecimal("12.99"))
.quantityOnHand(4)
.upc(123456789012L)
.createdDate(OffsetDateTime.now())
.lastModifiedDate(OffsetDateTime.now())
.build();
// Spring context will initialize the MockMvc
// via auto-configuration of Spring Boot
}
@AfterEach
void tearDown() {
// beerService is a Spring component now,
// Mockito knows it's a mock instance,
// doesn't know to which context it is used
reset(beerService);
}
@Test
void testGetBeerById() throws Exception {
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ");
given(beerService.findBeerById(any())).willReturn(validBeer);
MvcResult result= mockMvc.perform(get("/api/v1/beer/" + validBeer.getId()))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(jsonPath("$.id", is(validBeer.getId().toString())))
.andExpect(jsonPath("$.beerName", is("Beer1")))
.andExpect(jsonPath("$.createdDate",
is(dateTimeFormatter.format(validBeer.getCreatedDate()))))
.andReturn();
System.out.println(result.getResponse().getContentAsString());
}
@DisplayName("List Ops - ")
@Nested
public class TestListOperations {
@Captor
ArgumentCaptor<String> beerNameCaptor;
@Captor
ArgumentCaptor<BeerStyleEnum> beerStyleEnumCaptor;
@Captor
ArgumentCaptor<PageRequest> pageRequestCaptor;
BeerPagedList beerPagedList;
@BeforeEach
void setUp() {
List<BeerDto> beers = new ArrayList<>();
beers.add(validBeer);
beers.add(BeerDto.builder().id(UUID.randomUUID())
.version(1)
.beerName("Beer4")
.upc(123123123122L)
.beerStyle(BeerStyleEnum.PALE_ALE)
.price(new BigDecimal("12.99"))
.quantityOnHand(66)
.createdDate(OffsetDateTime.now())
.lastModifiedDate(OffsetDateTime.now())
.build());
beerPagedList = new BeerPagedList(beers, PageRequest.of(1, 1), 2L);
given(beerService.listBeers(beerNameCaptor.capture(), beerStyleEnumCaptor.capture(),
pageRequestCaptor.capture())).willReturn(beerPagedList);
}
@DisplayName("Test list beers - no parameters")
@Test
void testListBeers() throws Exception {
mockMvc.perform(get("/api/v1/beer")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(jsonPath("$.content", hasSize(2)))
.andExpect(jsonPath("$.content[0].id", is(validBeer.getId().toString())));
}
// Allowing Spring Boot to manage the Jackson configuration
}
}
Using TestRestTemplate
BeerControllerIT
//Creating the web environment and the embedded server
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class BeerControllerIT {
@Autowired
private TestRestTemplate restTemplate;
@Test
void testListBeers() {
BeerPagedList beerPagedList = restTemplate.getForObject("/api/v1/beer", BeerPagedList.class);
assertThat(beerPagedList.getContent()).hasSize(3);
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。