Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interrogation about Spring MVC test API's model().attribute() method

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.

like image 799
balteo Avatar asked Sep 20 '13 15:09

balteo


1 Answers

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.

like image 80
Sotirios Delimanolis Avatar answered Oct 25 '22 08:10

Sotirios Delimanolis