Java 如何为包含错误/BindingResult的控制器编写测试?
我正在使用SpringBoot和SpringMVC开发一个简单的网站,我遇到了一个无法编写测试的场景。如何测试控制器如何处理Java 如何为包含错误/BindingResult的控制器编写测试?,java,spring-mvc,junit,thymeleaf,Java,Spring Mvc,Junit,Thymeleaf,我正在使用SpringBoot和SpringMVC开发一个简单的网站,我遇到了一个无法编写测试的场景。如何测试控制器如何处理错误,这些错误会影响用户界面,但不包括在模型和视图中 我在HTML表单中显示错误消息时遇到了问题,在经历了许多挫折之后,我发现这是因为我在将表单对象作为对象返回到ModelAndView之前覆盖了表单对象 这就是问题中的代码 @PostMapping ModelAndView processPost(@Valid IdAndAmountForm idAndAmountFor
错误
,这些错误会影响用户界面,但不包括在模型和视图中
我在HTML表单中显示错误消息时遇到了问题,在经历了许多挫折之后,我发现这是因为我在将表单对象作为对象返回到ModelAndView
之前覆盖了表单对象
这就是问题中的代码
@PostMapping
ModelAndView processPost(@Valid IdAndAmountForm idAndAmountForm, Errors errors) {
if (errors.hasErrors()) {
var beer = service.findBeerById(idAndAmountForm.getId());
return new ModelAndView("beerView")
.addObject("beer", beer)
.addObject("idAndAmountForm", idAndAmountForm);
} else {
cart.add(idAndAmountForm);
return new ModelAndView("redirect:/cart");
}
}
它的工作/行为与预期一致,在删除HTML验证时,用适当的消息填充span
<form th:action="@{/beer}" th:object="${idAndAmountForm}" method="post">
<label>
Amount
<span th:errors="*{amount}"></span>
<input th:field="*{amount}" type="number" min="1" required>
</label>
数量
我的错误出现在控制器的第7行,在那里我以前有.addObject(“idAndAmountForm”,new idAndAmountForm())代码>
没有与新表单关联的错误,因此未显示任何错误消息。或者这就是我认为发生的事情
现在,我如何编写一个测试来检测这种错误行为呢?
我花了一些时间剖析模型
,寻找我知道以某种方式传递给Thymeleaf模板的错误消息,然后得出结论,错误消息由Spring单独处理。帮助我看到了我想在测试中检查的BindingResult
或Errors
对象。但是,它不是我编写的任何方法的返回值的一部分
我想我可以尝试为viewsolver
或任何在我的控制器和模板之间自动生成的对象中介编写一个测试,或者我可以剪切我的控制器类以允许我的测试类访问错误。这两个似乎都是坏主意。目前的解决方案是考虑场景太多的测试,但是我不喜欢在原理上认为这是不可测试的。< P>可以用Spring编写一个控制器测试来实现您想要的。strong>SpringMVC测试框架提供了一个非常好的、易于阅读的fluent API,可用于使用MockMvc测试MVC中的所有场景
对于您的用例,测试模型属性绑定结果错误,您可能会编写一个使用MockMvcResultMatchers和static status()、model()、view()、flash()等的测试
花点时间来探索这些方法,看看你可以调用哪些方法。
例如,在模型中,您有多个与fieldErrors相关的方法,并且您可以根据需要精确地进行检查。
最终,您的测试类将如下所示:
mockMvc.perform(post(YOUR_URL).contentType(APPLICATION_FORM_URLENCODED)
.param(...)
.param(...)
.andExpect(model().hasErrors())
.andExpect(model().attributeHasFieldErrors(FORM_MODEL_NAME, "field"))
.andExpect(model().attributeHasFieldErrorCode(FORM_MODEL_NAME, "anotherfield", "error")
.andExpect(view().name(YOUR_VIEW));
有关Spring MVC测试框架的更多信息,请参见:
您可以使用Spring编写控制器测试,以实现所需的功能SpringMVC测试框架提供了一个非常好的、易于阅读的fluent API,可用于使用MockMvc测试MVC中的所有场景
对于您的用例,测试模型属性绑定结果错误,您可能会编写一个使用MockMvcResultMatchers和static status()、model()、view()、flash()等的测试
花点时间来探索这些方法,看看你可以调用哪些方法。
例如,在模型中,您有多个与fieldErrors相关的方法,并且您可以根据需要精确地进行检查。
最终,您的测试类将如下所示:
mockMvc.perform(post(YOUR_URL).contentType(APPLICATION_FORM_URLENCODED)
.param(...)
.param(...)
.andExpect(model().hasErrors())
.andExpect(model().attributeHasFieldErrors(FORM_MODEL_NAME, "field"))
.andExpect(model().attributeHasFieldErrorCode(FORM_MODEL_NAME, "anotherfield", "error")
.andExpect(view().name(YOUR_VIEW));
有关Spring MVC测试框架的更多信息,请参见: