使用注释时模拟Spring MVC BindingResult

Al *_*wer 14 unit-testing mocking spring-mvc

我正在迁移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
    }
Run Code Online (Sandbox Code Playgroud)

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

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

如何模拟一个Spring BindingResult用于单元测试?

Ted*_*ngs 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);
}
Run Code Online (Sandbox Code Playgroud)

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


Mar*_*ark 17

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

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

  • 嗨马克,这让我走在正确的轨道上谢谢.使用BindingResult bindingResult = new BeanPropertyBindingResult(command,"command"); 并且在我的测试中将命令对象粘贴在模型中似乎将我的测试排除在外. (4认同)