本文介紹了為什么測試成功時(shí)MockMvc請求檢索空的響應(yīng)正文?的處理方法,對大家解決問題具有一定的參考價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧!
問題描述
我正在嘗試測試我的Spring Boot REST控制器,以檢查如果Bean驗(yàn)證失敗,請求是否發(fā)送屬性錯(cuò)誤。
我有一個(gè)@RestController:
@RestController
@RequestMapping("/restaurants")
public class RestaurantsApiController {
private final RestaurantService restaurantService;
private final ProductRepository productRepository;
private final ProductMapper productMapper;
public RestaurantsApiController(RestaurantService restaurantService, ProductRepository productRepository, ProductMapper productMapper) {
this.restaurantService = restaurantService;
this.productRepository = productRepository;
this.productMapper = productMapper;
}
@PostMapping("{id}/products")
public ResponseEntity<ProductDto> addProduct(@PathVariable Long id,
@Valid @RequestBody ProductDto productDto){
Product product = this.restaurantService.addProduct(id, productMapper.productDtoToProduct(productDto));
return new ResponseEntity<>(productMapper.productToProductDto(product), HttpStatus.CREATED);
}
我有一個(gè)帶有@ControllerAdance注釋的自定義異常處理程序:
@ControllerAdvice
public class ExceptionControllerAdvice {
@ExceptionHandler({MethodArgumentNotValidException.class})
public ResponseEntity<Object> validationException(MethodArgumentNotValidException ex, WebRequest request) {
....
// here i format my custom error message
return new ResponseEntity<>(apiError, new HttpHeaders(), apiError.getStatus());
}
它運(yùn)行良好,如果驗(yàn)證失敗,則向我發(fā)送此自定義響應(yīng):
{
"status": "BAD_REQUEST",
"errors": {
"price": "doit être supérieur ou égal à 0",
"name": "ne doit pas être nul",
"category": "ne doit pas être nul"
}
}
我正在嘗試使用mock Mvc測試此測試類的行為:
@ExtendWith(MockitoExtension.class)
class RestaurantsApiControllerTest {
@Mock
private RestaurantService restaurantService;
@Mock
private ProductRepository productRepository;
@Mock
private ProductMapper productMapper;
@InjectMocks
private RestaurantsApiController controller;
MockMvc mockMvc;
@BeforeEach
void setUp() {
mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
}
@Test
void givenInvalidFrom_whenAddProduct_ThenShouldThrowException() throws Exception {
// productDto miss name, category and have negative value for price which is forbidden by validations annotations
ProductDto productDto = ProductDto.builder().id(1L).price(-10.5D).build();
MvcResult mvcResult = mockMvc.perform(post("/restaurants/1/products")
.contentType(MediaType.APPLICATION_JSON)
.content(asJsonString(productDto)))
.andExpect(status().isBadRequest())
.andReturn();
String result = mvcResult.getResponse().getContentAsString();
then(restaurantService).shouldHaveNoInteractions();
}
測試完全通過,我可以在日志中看到驗(yàn)證異常預(yù)期正常:
14:53:30.345 [main] WARN org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver - Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument ...
//I removed the rest of the message for readability, but each validation exception appears here properly
14:53:30.348 [main] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - Completed 400 BAD_REQUEST
但是我找不到一種方法來測試我的錯(cuò)誤映射是否包含我期望的字段。當(dāng)我嘗試使用:
檢索響應(yīng)正文時(shí)
String result = mvcResult.getResponse().getContentAsString();
字符串為空,我找不到任何測試響應(yīng)正文的方法。
我完全沒有想法,如果能幫上忙,我會(huì)非常感激的!
非常感謝!
推薦答案
使用Builder配置MockMvc實(shí)例時(shí),請進(jìn)行以下更新:
MockMvcBuilders
.standaloneSetup(controller)
.setControllerAdvice(new ExceptionControllerAdvice())
.build()
您應(yīng)該手動(dòng)設(shè)置控制器建議以模擬MVC上下文,否則它將被忽略。
在此更新之后,您將收到錯(cuò)誤響應(yīng)中的正文。如果您想驗(yàn)證Json Body,請使用上面答案中的json路徑API。
這篇關(guān)于為什么測試成功時(shí)MockMvc請求檢索空的響應(yīng)正文?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,






