14

我正在迁移 Spring MVC 控制器以使用较新的样式注释,并希望对验证命令对象的控制器方法进行单元测试(请参见下面的简单示例)。

 @RequestMapping(method = RequestMethod.POST)
public String doThing(Command command, BindingResult result,
                    HttpServletRequest request, HttpServletResponse response,
                    Map<String, Object> model){ 
    ThingValidator validator = new ThingValidator();
    validator.validate(command, result);
... other logic here
    }

我的问题是我必须在单元测试中调用控制器的方法,并提供模拟值以满足其签名以正确执行代码,并且我无法弄清楚如何模拟 BindingResult。

在旧样式的 Controller 中,签名只是简单地采用了 HttpServletRequest 和 HttpServletResponse,它们很容易被模拟,但是由于新注释样式的灵活性,人们必须通过签名传递更多内容。

如何模拟 Spring BindingResult 以在单元测试中使用?

4

3 回答 3

18

您还可以使用 Mockito 之类的东西创建 BindingResult 的模拟并将其传递给您的控制器方法,即

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.verifyZeroInteractions;

@Test
public void createDoesNotCreateAnythingWhenTheBindingResultHasErrors() {
    // Given
    SomeDomainDTO dto = new SomeDomainDTO();
    ModelAndView mv = new ModelAndView();

    BindingResult result = mock(BindingResult.class);
    when(result.hasErrors()).thenReturn(true);

    // When
    controller.create(dto, result, mv);

    // Then
    verifyZeroInteractions(lockAccessor);
}

这可以为您提供更大的灵活性并简化脚手架。

于 2011-10-13T18:17:52.127 回答
17

BindingResult 是一个接口,所以你不能简单地传入该接口的 Springs 实现之一吗?

我不在我的 Spring MVC 代码中使用注释,但是当我想测试验证器的 validate 方法时,我只需传入一个 BindException 实例,然后使用它在 assertEquals 等中返回的值。

于 2009-05-18T12:40:25.437 回答
1

本答案所述

ABindingResult由 Spring MVC 为每个传入的 HTTP 请求创建。

因此,您不想模拟BindingResult.

而不是直接调用这些方法,您应该对控制器进行真正的 http 调用,或者使用MockMvc.perform. 这是官方文档的教程 ,展示了如何做到这一点。

于 2019-10-02T05:32:07.653 回答