spring-boot - 如何在 Spring Boot 测试中模拟 BindingResult

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

我有以下 Controller :

@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

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

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

提前致谢。

最佳答案

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

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

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

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

关于spring-boot - 如何在 Spring Boot 测试中模拟 BindingResult,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52001043/

相关文章:

java - junit 流图 Java 8

java - Jackson 将 XML 与根序列化为抽象类

java - 如何测试 MapStruct 映射器实现并模拟其依赖项

java - JUnit 5 - 使用 JUnit Jupiter 引擎时 IntelliJ IDEA 中的空测试套件

java - 如何在通过构造函数接收参数的类中使用@SpyBean?

java - Spring RestTemplate - 在 GET 中传入对象参数

java - 如何在命令 "java -Djasypt.encryptor.password=somepassword -jar name.jar"中隐藏密码

mocking - 如何将 @InjectMocks 和 initMocks() 与具有必需 String 参数的对象一起使用?

spring - @ControllerAdvice 单元测试 Controller 中的 Autowired MessageSource null

java - 模拟对象返回 null