使用Spring MockMvc

时间:2017-10-02 09:03:56

标签: mockmvc spring-mvc-test

我添加了一个拦截器,它在会话中查找loggedInUser并重定向到登录页面并显示错误消息,指示用户登录以继续。我正在使用flash属性传递此消息。当我运行应用程序时,整个设置工作正常。

但是我无法使用MockMvc声明flash属性。

public class LoginInterceptor extends HandlerInterceptorAdapter{

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String loginUrl = request.getContextPath() + "/login";
        if(request.getSession().getAttribute("loggedInUser") == null) {
            FlashMap flashMap = new FlashMap();
            flashMap.put("loginError", "Please login to continue");
            FlashMapManager flashMapManager = RequestContextUtils.getFlashMapManager(request);
            flashMapManager.saveOutputFlashMap(flashMap, request, response);
            response.sendRedirect(loginUrl);
            return false;
        }
        return true;
    }
}

在测试用例中,我可以断言当我没有登录时调用“/ user”,它会被重定向到“/ login”页面。但是我无法断言flash属性。

@WebMvcTest(UserProfileController.class)
@RunWith(SpringRunner.class)
public class UserProfileControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void testForNotLoggedInCall() throws Exception{
        MvcResult mvcResult = mockMvc.perform(get("/user")).andDo(print())
        .andExpect(status().is3xxRedirection())
        .andExpect(flash().attribute("loginError", equalTo("Please login to continue")))
        .andExpect(redirectedUrl("/login"))
        .andReturn();
        assertNotNull(mvcResult);
        List<HandlerInterceptor> interceptors = Arrays.asList(mvcResult
                .getInterceptors());
        assertTrue(
                "Expecting login interceptor in this path for cases where there is no logged in user",
                interceptors.stream().anyMatch(
                        i -> i.getClass().equals(LoginInterceptor.class)));
        FlashMap flashMap = mvcResult.getFlashMap();
        assertNotNull(flashMap);
        assertEquals("Please login to continue", flashMap.get("loginError"));
    }
}

我使用过这两种方法: 1)

andExpect(flash().attribute("loginError", equalTo("Please login to continue")))

2)还可以从mvcResult获取flashMap:

FlashMap flashMap = mvcResult.getFlashMap();

没有任何作用。

并且下面的print()结果显示: flash映射具有预期的属性,但MockHttpServletRequest中的flashAttribute为null

有人可以解释我做错了什么吗?以及如何断言flash属性?

  

2017-10-02 14:09:12.470 DEBUG 5836 --- [主要]   s.w.s.m.m.a.RequestMappingHandlerMapping:查找处理程序方法   for path / user 2017-10-02 14:09:12.502 TRACE 5836 --- [
  main] s.w.s.m.m.a.RequestMappingHandlerMapping:找到1个匹配项   [/ user]的映射:[{[/ user],methods = [GET]}] 2017-10-02   14:09:12.517 DEBUG 5836 --- [主要]   s.w.s.m.m.a.RequestMappingHandlerMapping:返回处理程序方法   [public org.springframework.web.servlet.ModelAndView   com.foo.library.controller.UserProfileController.showUserProfilePage(的javax.servlet.http.HttpSession)]   2017-10-02 14:09:12.517 DEBUG 5836 --- [主要]   o.s.b.f.s.DefaultListableBeanFactory:返回缓存的实例   singleton bean的用户'userProfileController'2017-10-02 14:09:12.533   TRACE 5836 --- [主要]   o.s.t.web.servlet.TestDispatcherServlet:测试处理程序适配器   [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter@253c1256]   2017-10-02 14:09:12.533 DEBUG 5836 --- [主要]   o.s.t.web.servlet.TestDispatcherServlet:Last-Modified值   [/ user]是: - 1    2017-10-02 14:09:12.533 DEBUG 5836 --- [main] o.s.w.s.support.SessionFlashMapManager:保存FlashMap = FlashMap   [attributes = {loginError =请登录以继续},   targetRequestPath = null,targetRequestParams = {}] 2017-10-02   14:09:12.533 TRACE 5836 --- [主要]   o.s.t.web.servlet.TestDispatcherServlet:清除线程绑定   请求上下文:   org.springframework.mock.web.MockHttpServletRequest@304a3655   2017-10-02 14:09:12.533 DEBUG 5836 --- [主要]   o.s.t.web.servlet.TestDispatcherServlet:已成功完成   要求2017-10-02 14:09:12.533 TRACE 5836 --- [主要]   o.s.w.c.s.GenericWebApplicationContext:发布事件   org.springframework.web.context.support.GenericWebApplicationContext@2fb3536e:   ServletRequestHandledEvent:url = [/ user];客户= [127.0.0.1]。   方法= [GET];的servlet = [];会话= 1;用户= [零]。时间= [78ms];   status = [确定] 2017-10-02 14:09:12.533 DEBUG 5836 --- [主要]   o.s.b.w.f.OrderedRequestContextFilter:清除线程绑定   请求上下文:   org.springframework.mock.web.MockHttpServletRequest@304a3655

     

MockHttpServletRequest:         HTTP方法= GET         请求URI = / user          参数= {}             标题= {}

     

处理程序:                Type = com.foo.library.controller.UserProfileController              Method = public org.springframework.web.servlet.ModelAndView   com.foo.library.controller.UserProfileController.showUserProfilePage(的javax.servlet.http.HttpSession)

     

异步:       异步启动= false        异步结果= null

     

已解决的异常:                Type = null

     

的ModelAndView:           查看名称= null                View = null               Model = null

     

FlashMap:          Attributes = null

     

MockHttpServletResponse:              状态= 302       错误消息= null             标题= {Location = [/ login]}        内容类型= null                身体=       转发的URL = null重定向的URL = / login             Cookies = []

修改

在进一步调试时,我发现FlashAttributeResultMatcher正在调查outputFlashMap以进行断言,我在拦截器中使用了FlashMapManager,该拦截器在会话中使用了另一个属性。

有人可以解释inputFlashMap, outputFlashMap and FlashMapManager之间的区别吗?我们使用它们的理想场景是什么?

0 个答案:

没有答案