【问题标题】:How to mock BindingResult in Spring Boot Test如何在 Spring Boot 测试中模拟 BindingResult
【发布时间】:2019-01-30 17:35:27
【问题描述】:

我有以下控制器:

@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 并且测试用例通过。

我做了很多搜索,但没有运气。有什么建议吗?

提前致谢。

【问题讨论】:

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


    【解决方案1】:

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

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

    因此,您不想模拟BindingResult。事实上,您可能也不想嘲笑 RequestValidator 的行为。相反,您最好使用RequestValidator 的实际实现,传入无效 请求数据(通过MockMvc),然后相应地验证响应。

    请注意,您应该能够包含在测试类中通过@Import(RequestValidator.class) 实现您的RequestValidator

    【讨论】:

    • 非常感谢@sam-brannen,这解决了我的问题。是的,你是对的,我应该使用RequestValidator 的真正实现。我删除了requestValidatorbindingResult,然后添加了@Import(RequestValidator.class),一切正常。
    猜你喜欢
    • 2016-12-09
    • 1970-01-01
    • 1970-01-01
    • 2021-05-28
    • 2018-05-01
    • 1970-01-01
    • 2019-09-28
    • 1970-01-01
    • 2020-08-13
    相关资源
    最近更新 更多