SpringWebMvcTest - 使用 @Valid 和自定义验证测试 Requestbody [英] SpringWebMvcTest - Test Requestbody using @Valid and custom validation

查看:47
本文介绍了SpringWebMvcTest - 使用 @Valid 和自定义验证测试 Requestbody的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试测试我的控制器端点和带有 @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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆