使用MockMvc测试Controller时,如何验证Flash属性为非空字符串?
嘿,我来帮你搞定这个MockMvc测试的问题!你遇到的断言异常,核心原因是混用了AssertJ和Hamcrest的匹配器——MockMvc的flash().attribute()断言要求传入Hamcrest的Matcher类型对象,但你用的isEmptyOrNullString()是AssertJ的方法,不是Hamcrest的匹配器,这才导致了那个看起来奇怪的错误提示。
给你两种可行的正确方案:
方案一:用Hamcrest原生匹配器组合验证
如果你的项目依赖的Hamcrest版本较低(低于2.x),可以用Hamcrest原生的匹配器组合来实现“非空且非null字符串”的验证:
import static org.hamcrest.Matchers.anyOf; import static org.hamcrest.Matchers.isEmptyString; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.nullValue; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.flash; // 测试代码中的断言部分 .andExpect(flash().attribute("errorDelete", not(anyOf(isEmptyString(), nullValue()))))
这个写法的逻辑很清晰:用anyOf把“空字符串”和“null”两种不符合要求的情况组合起来,再用not取反,就精准验证了目标flash属性是非空且非null的字符串。
方案二:用Hamcrest 2.x+的简洁匹配器
如果你的项目已经使用了Hamcrest 2.x及以上版本,Hamcrest新增了emptyOrNullString()这个专门的匹配器,和你之前想用的AssertJ方法功能完全一致,但它是标准的Hamcrest Matcher,可以直接在MockMvc断言里使用:
import static org.hamcrest.Matchers.emptyOrNullString; import static org.hamcrest.Matchers.not; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.flash; // 更简洁的断言写法 .andExpect(flash().attribute("errorDelete", not(emptyOrNullString())))
这个写法和你最初的思路最接近,而且完全符合MockMvc的断言要求。
关键注意点
一定要检查你的导入包:确保导入的是Hamcrest的匹配器(org.hamcrest.Matchers.*),而不是AssertJ的断言方法(org.assertj.core.api.Assertions.*)——这是很多人犯的小错误,但会直接导致断言异常。
当你的flash属性值是error.last_user这种非空字符串时,上面两种方案的断言都会顺利通过,不会再抛出之前的错误。
内容的提问来源于stack exchange,提问作者Michael

