I am trying to test the following controller method using the Spring MVC test API:
@RequestMapping(value = "/preference/email", method = RequestMethod.GET, produces = "text/html")
public String emailForm(@ModelAttribute EmailInfo emailInfo, Model model, @CurrentMember Member member) {
emailInfo.setEmail(member.getEmail());
emailInfo.setActivated(member.isActivated());
emailInfo.setToken(member.getToken());
model.addAttribute("emailInfo", emailInfo);
return "preference";
}
When I debug the following test method...
@Test
public void shouldPopulateEmailInfo() throws Exception {
when(currentMemberHandlerMethodArgumentResolver.supportsParameter(any(MethodParameter.class))).thenReturn(Boolean.TRUE);
when(currentMemberHandlerMethodArgumentResolver.resolveArgument(any(MethodParameter.class), any(ModelAndViewContainer.class), any(NativeWebRequest.class), any(WebDataBinderFactory.class))).thenReturn(currentMember);
mockMvc.perform(get("/preference/email"))//
.andDo(print())//
.andExpect(model().attribute("emailInfo.email", "[email protected]"));//
}
... I do see that "[email protected]" is set on the email field of emailInfo.
However, I systematically get:
java.lang.AssertionError: Model attribute 'emailInfo.email' expected:<[email protected]> but was:<null>
at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:60)
at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:89)
at org.springframework.test.web.servlet.result.ModelResultMatchers$2.match(ModelResultMatchers.java:68)
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:141)
at com.bignibou.tests.controller.preference.PreferenceControllerEmailManagementTest.shouldPopulateEmailInfo(PreferenceControllerEmailManagementTest.java:109)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
There is something I don't get with the Spring Mvc Test API.... Can anyone please help?
edit: Here is what I have come up with after taking into account the provided answer:
.andExpect(model().attribute("emailInfo", Matchers.hasProperty("email", Matchers.equalTo("[email protected]"))));//
It works fine now.
Model attributes are String-key Object-value pairs. There is no expression resolving going on. When you do
model().attribute("emailInfo.email", "[email protected]"));//
You are asking if there is a Model attribute with key emailInfo.email that has the specified value. The answer is obviously no since you don't have a Model attribute with such a key.
What you have is
model.addAttribute("emailInfo", emailInfo);
which is a Model attribute with key emailInfo that holds an object of type EmailInfo. You'll need to compare the email field of the EmailInfo object yourself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With