亲爱的开发者在stackoverflow,
我真的很感谢你帮助解决我在测试我的一个Spring MVC控制器时无法解决的棘手问题。
可以在此处找到整个代码存储库:https://github.com/peerpub/peerpub
环境:
问题描述:
在尝试使用Mockito / MockMVC的单元测试方法为DocTypeAdminCtrl.java
进行详细测试时,我无法基于Map
绑定数据,而简单String
并且Boolean
工作得很好。当我尝试在我的全栈集成测试中使用它时已经发生了同样的情况(已经尝试过)。
通过网络浏览器使用该应用程序时,不会出现此问题,因此这似乎完全与测试相关。
DocTypeAdminCtrlTest.java
中名为editPost...()
的所有测试均失败。示例摘录自mvn test
:
Tests run: 7, Failures: 3, Errors: 0, Skipped: 0, Time elapsed: 0.437 sec <<< FAILURE! - in de.fzj.peerpub.doc.doctype.DocTypeAdminCtrlTest
editPostFormSuccess Time elapsed: 0.103 sec <<< FAILURE!
java.lang.AssertionError: Status expected:<302> but was:<200>
at de.fzj.peerpub.doc.doctype.DocTypeAdminCtrlTest.editPostFormSuccess(DocTypeAdminCtrlTest.java:148)
editPostFormNonMatchingNames Time elapsed: 0.046 sec <<< FAILURE!
java.lang.AssertionError: Model attribute 'doctype' expected: <DocTypeForm(name=vfAtXQ, displayName=01p14G7v22, system=false, multiDoc=true, attributes=[6Vuzhn, zKXSTl], mandatory={6Vuzhn=null, zKXSTl=true}, defaults={6Vuzhn=, zKXSTl=sooeOYb6Ld})> but was:<DocTypeForm(name=vfAtXQ, displayName=01p14G7v22, system=false, multiDoc=true, attributes=[6Vuzhn, zKXSTl], mandatory=null, defaults=null)>
at de.fzj.peerpub.doc.doctype.DocTypeAdminCtrlTest.editPostFormNonMatchingNames(DocTypeAdminCtrlTest.java:165)
editPostFormExceptionDTO Time elapsed: 0.041 sec <<< FAILURE!
java.lang.AssertionError: Model attribute 'doctype' expected:<DocTypeForm(name=GPzldO, displayName=mIV7Utta1Y, system=false, multiDoc=false, attributes=[8GsYhQ, bZGkd2], mandatory={8GsYhQ=null, bZGkd2=true}, defaults={8GsYhQ=SfoDlEiYAz, bZGkd2=k4uaLxx8yf})> but was:<DocTypeForm(name=GPzldO, displayName=mIV7Utta1Y, system=false, multiDoc=false, attributes=[8GsYhQ, bZGkd2], mandatory=null, defaults=null)>
at de.fzj.peerpub.doc.doctype.DocTypeAdminCtrlTest.editPostFormExceptionDTO(DocTypeAdminCtrlTest.java:210)
请注意,属性mandatory
和defaults
始终设置为null
,同时存在于模型中。我确认即使我的自定义验证器DocTypeFormValidator.java也没有看到这些数据。这也导致我的editPostFormSuccess
测试失败:由于属性设置为null
,验证器不满意,绑定结果包含错误。
当我对单元/集成测试我的DocTypeAdminCtrl.java
使用的任何类型的东西时,我很确定在我的控制器类或我的测试类中一定有一些缺失或错误。
MockMvcRequestBuilderUtils.postForm()
可能存在错误(请参阅upstream),但我实际上不知道如何使用包含{{1}的测试数据编写备用post()
请求}和Map
。通过调试器查看List
,所有数据似乎都存在,包括MockHttpServletRequestBuilder
和mandatory
,所以这可能是一个不太重要的事情要检查......?
引起我注意的一些可疑调试日志输出行:
defaults
在StackOverflow和Google上搜索这些错误并没有多大帮助......: - (
重现的步骤:
只需克隆我的仓库,切换到我的功能分支org.springframework.beans.BeanUtils - No property editor [java.util.MapEditor] found for type java.util.Map according to 'Editor' suffix convention
org.springframework.core.annotation.AnnotationUtils - Failed to meta-introspect annotation interface org.springframework.web.bind.annotation.ModelAttribute: java.lang.NullPointerException
并运行oliver_dtsvc
。
那里有人有线索吗?非常感谢任何帮助!
答案 0 :(得分:0)
这与使用MockMvcRequestBuilderUtils.postForm()
作为我的助手完全相关。
当我在editPostFormSuccess()
中手动构建POST请求作为概念证明时,测试按预期运行:
ResultActions result = mvc.perform(post("/admin/doctypes/edit/{name}", this.valid.getName())
.param("name", this.valid.getName())
.param("displayName", this.valid.getDisplayName())
.param("system", this.valid.getSystem().toString())
.param("multiDoc", this.valid.getMultiDoc().toString())
.param("attributes[0]", this.valid.getAttributes().get(0))
.param("attributes[1]", this.valid.getAttributes().get(1))
.param("mandatory["+this.valid.getAttributes().get(0)+"]", this.valid.getMandatory().get(this.valid.getAttributes().get(0)).toString())
.param("mandatory["+this.valid.getAttributes().get(1)+"]", this.valid.getMandatory().get(this.valid.getAttributes().get(1)).toString())
.param("defaults["+this.valid.getAttributes().get(0)+"]", this.valid.getDefaults().get(this.valid.getAttributes().get(0)))
.param("defaults["+this.valid.getAttributes().get(1)+"]", this.valid.getDefaults().get(this.valid.getAttributes().get(1)))
);
因此,我将尝试弄清楚如何扩展/改进MockMvcRequestBuilderUtils
,因为它有助于构建这些请求。
上游问题:https://github.com/f-lopes/spring-mvc-test-utils/issues/3