SpringWebMvcTest - 使用 @Valid 和自定义验证测试 Requestbody [英] SpringWebMvcTest - Test Requestbody using @Valid and custom validation
问题描述
我正在尝试测试我的控制器端点和带有 @Valid
注释的请求体.我的 Testclass 如下所示:
I am trying to test my controller endpoint and my requestbody annotated with @Valid
annotation. My Testclass looks like the follow:
@RunWith(SpringRunner.class)
@WebMvcTest(value = BalanceInquiryController.class, secure = false)
public class BalanceInquiryControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private BalanceInquiryController balanceInquiryController;
@Test
public void testGetBalanceInquiry() throws Exception {
RequestBuilder requestBuilder = MockMvcRequestBuilders
.post("/com/balanceInquiry")
.accept(MediaType.APPLICATION_JSON)
.content("{"comGiftCard":{"cardNumber":"1234567890","pinNumber":"0123"},"comMerchant":"MERCHANT1"}")
.contentType(MediaType.APPLICATION_JSON);
MvcResult mvcResult = mockMvc.perform(requestBuilder).andReturn();
MockHttpServletResponse response = mvcResult.getResponse();
assertEquals(HttpStatus.OK.value(), response.getStatus());
}
}
我的控制器 - @PostMapping
看起来像这样:
My Controller - @PostMapping
looks like that:
@PostMapping(value = "/com/balanceInquiry")
public ResponseEntity<?> getBalanceInquiry(@Valid @RequestBody BalanceInquiryModel balanceInquiry, Errors errors) {
if (errors.hasErrors()) {
return new ResponseEntity<String>("Validation error", HttpStatus.BAD_REQUEST);
}
//do any stuff...
return new ResponseEntity<BalanceInquiryResponse>(balanceInquiryResponse, HttpStatus.OK);
}
我的 BalanceInquiryModel
使用 @Valid
进行注释,并在后面有一些休眠和自定义验证.这些验证都可以,并且已经过单元测试.
My BalanceInquiryModel
is annotated with @Valid
and has some hibernate and custom validations behind. Those validations are all ok and already unit tested.
我想测试的是我的端点,我发送一个有效的 json 请求正文,期望得到 200 响应,以及一个无效的 json 请求正文,期望得到由集合 @Valid
验证的 400 响应实施.
What I like to test is my endpoint where I send a valid json request body expecting a 200 response and also an invalid json request body expecting a 400 response validated by the set @Valid
implementation.
例如一个无效的调用是不发送 pinNumber 或 length
For example an unvalid call is to send no pinNumber or length < 4.
我已经阅读了一些线程和一些使用 MockMvcBuilders.standaloneSetup()
来模拟完整的控制器.但我不会做一个完整的集成测试.
I have read some threads and some uses MockMvcBuilders.standaloneSetup()
to mock the full controller. But I wont do a full integration test.
不太确定如何处理这种情况以及是否应该继续.
Not quite sure how to go on with this situation and if I should go on.
P.S.:目前,无论验证是否应该给出错误,我总是得到 200 响应.
P.S.: At the moment I get always a 200 response no matter if the validation should give an error or not.
这里是要点了解更多代码和验证类/模型.
Here a gist for more code and the validation classes/models.
推荐答案
这是我在项目中工作的一个例子希望对你有所帮助:
Here's one of my example I work on my project hope it help you out:
我有一个全局异常处理程序来处理我的 MethodArgumentNotValidException 并抛出它
I have a global exception handler to handler my MethodArgumentNotValidException and throw it
@RequestMapping(value = "/add", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<User> createUser(@Valid @RequestBody User user) {
User savedUser = userService.save(user);
return new ResponseEntity<User>(savedUser, HttpStatus.CREATED);
}
public void testAdduser() throws Exception{
final User request = new User();
request.setFirstName("Test");
request.setLastName("some description");
mockMvc.perform(post(END_POINT+"/add")
.contentType(MediaType.APPLICATION_JSON)
.content(stringify(request))
).andDo(print()).andExpect(status().isUnprocessableEntity())
;
}
private String stringify(Object object) throws JsonProcessingException {
return new ObjectMapper().writeValueAsString(object);
}
更新:
我认为您的主要问题是您使用 @WebMvcTest 而不是 @SpringBootTest.
I think your main problem is that you are using @WebMvcTest in stead of @SpringBootTest.
两者的区别在于:
@SpringBootTest 注释将加载完整的应用程序并注入所有可能很慢的 bean.
@SpringBootTest annotation will loads complete application and injects all the beans which is can be slow.
@WebMvcTest - 用于测试控制器层.它不会在 @RestController 旁边注入其他 bean
@WebMvcTest - for testing the controller layer. it doesn't inject other bean beside the @RestController
因此,如果您只是测试纯控制器以查看您是否可以到达端点,那么您可以使用 @WebMvcTest 这将使您的测试运行得更快.
so if you are just testing just pure controller to see u can reach the endpont then you can just use @WebMvcTest which will make your test run faster.
但在您的情况下,您希望它运行 spring 验证,您需要使用 @SpringBootTest
but in your case, you want it to run the spring validation, you will need to use @SpringBootTest
详细说明:https://spring.io/guides/gs/testing-web/
这篇关于SpringWebMvcTest - 使用 @Valid 和自定义验证测试 Requestbody的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!