如何在Spring Boot Test中模拟BindingResult

时间:2018-08-24 09:07:38

标签: spring-boot mockito spring-test spring-test-mvc

我有以下控制器:

@RestController
@RequestMapping(value = ROOT_MAPPING)
public class GatewayController
{
    @Autowired
    private RequestValidator requestValidator;

    @InitBinder
    protected void initBinder(WebDataBinder binder)
    {
        binder.addValidators(requestValidator);
    }

    @PostMapping(value = REDIRECT_MAPPING)
    public ResponseEntity<ResponseDTO> redirectEndpoint(@Validated @RequestBody RequestDTO requestDTO, BindingResult result)
    {
        if (result.hasErrors())
        {
            // Handle validation errors
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
        }

        // Do other stuff
        return ResponseEntity.status(HttpStatus.OK).build();
    }
}

这个测试课:

@RunWith(SpringRunner.class)
@WebMvcTest(GatewayController.class)
public class GatewayControllerTest
{
    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private RequestValidator requestValidator;

    @MockBean
    private BindingResult bindingResult;

    private JacksonTester<RequestDTO> requestJacksonTester;

    @Before
    public void setUp() throws Exception
    {
        JacksonTester.initFields(this, new ObjectMapper());
        Mockito.when(requestValidator.supports(ArgumentMatchers.any())).thenReturn(true);
    }

    @Test
    public void whenRedirectWithValidationErrorsThenBadRequestReturned() throws Exception
    {
        RequestDTO request = new RequestDTO();
        // Set some values

        Mockito.when(bindingResult.hasErrors()).thenReturn(true);

        mockMvc.perform(MockMvcRequestBuilders.post(ROOT_MAPPING + REDIRECT_MAPPING).contentType(MediaType.APPLICATION_JSON).content(requestJacksonTester.write(request).getJson())).andExpect(MockMvcResultMatchers.status().isBadRequest());
    }
}

当我运行此代码时,测试用例由于以下原因而失败:状态 预期:400 实际:200

因此,我想做的是模拟BindingResult,它作为参数传递给Controller中的redirectEndpoint方法,以便在调用bindingResult.hasErrors()时应返回true,并且测试用例通过。

我进行了很多搜索,但是没有运气。有什么建议可以做到吗?

谢谢。

1 个答案:

答案 0 :(得分:0)

BindingResult不是ApplicationContext中的 bean 。因此,您不能通过@MockBean 模拟它。

Spring MVC为每个传入的HTTP请求为您创建一个BindingResult

因此,您不想模拟BindingResult。实际上,您可能也不想模拟RequestValidator的行为。相反,理想情况下,您应该使用RequestValidator的真实实现,通过MockMvc传入无效请求数据,然后相应地验证响应。

请注意,您应该能够通过测试类上的RequestValidator 包括您的@Import(RequestValidator.class)的真实实现。