首页 文章

使用MockMvc在Spring MVC中进行单元测试/登录

提问于
浏览
8

我有一个使用Spring MVC创建的非常简单的REST应用程序 . (代码可在GitHub获得 . )它有一个简单的WebSecurityConfigurer如下:

@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
    httpSecurity
            .csrf().disable()
            .exceptionHandling()
                .authenticationEntryPoint(authenticationEntryPoint)
                .and()
            .authorizeRequests()
                .antMatchers("/user/new").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login").permitAll()
                .successHandler(authenticationSuccessHandler)
                .failureHandler(authenticationFailureHandler)
                .and()
            .logout()
                .permitAll()
                .logoutSuccessHandler(logoutSuccessHandler);
}

当我运行应用程序时,自定义控制器和登录/注销页面都可以正常工作 . 我甚至可以unit test /user/new 来自 MockMvc . 但是,当我尝试使用以下函数测试 /login

@Test
public void testUserLogin() throws Exception {
    RequestBuilder requestBuilder = post("/login")
            .param("username", testUser.getUsername())
            .param("password", testUser.getPassword());
    mockMvc.perform(requestBuilder)
            .andDo(print())
            .andExpect(status().isOk())
            .andExpect(cookie().exists("JSESSIONID"));
}

它失败如下:

MockHttpServletRequest:
         HTTP Method = POST
         Request URI = /login
          Parameters = {username=[test-user-UserControllerTest], password=[test-user-UserControllerTest-password]}
             Headers = {}

             Handler:
                Type = org.springframework.web.servlet.resource.ResourceHttpRequestHandler

               Async:
   Was async started = false
        Async result = null

  Resolved Exception:
                Type = org.springframework.web.HttpRequestMethodNotSupportedException

        ModelAndView:
           View name = null
                View = null
               Model = null

            FlashMap:

MockHttpServletResponse:
              Status = 405
       Error message = Request method 'POST' not supported
             Headers = {Allow=[HEAD, GET]}
        Content type = null
                Body = 
       Forwarded URL = null
      Redirected URL = null
             Cookies = []

java.lang.AssertionError: Status expected:<200> but was:<405>

但是当我运行应用程序而不是测试时,我很漂亮 POST/login 正在工作 . 此外,当我尝试发出 GETHEAD 请求时(如日志的 Headers = {Allow=[HEAD, GET]} 行中所示),这次我收到404.关于发生了什么的任何想法以及如何解决它?

3 回答

  • 1

    我现在注意到了github链接 . 我相信您还需要为您的测试配置安全过滤器 . 就像是

    mockMvc = MockMvcBuilders.webApplicationContextSetup(webApplicationContext)
                    .addFilter(springSecurityFilterChain)
                    .build();
    

    可能需要一些其他设置,您可以查看http://www.petrikainulainen.net/programming/spring-framework/integration-testing-of-spring-mvc-applications-security/获取灵感 .

  • 5

    您可以使用Spring安全测试类来测试基于表单的登录 . 您需要执行以下操作来测试基于表单的登录 .

    Maven dependency:

    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-test</artifactId>
        <version>4.0.0.M1</version>
        <scope>test</scope>
    </dependency>
    
    <repositories>
        <repository>
            <id>spring-snasphot</id>
            <url>https://repo.spring.io/libs-snapshot</url>
        </repository>
    </repositories>
    

    Test class:

    import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.formLogin;
    
    RequestBuilder requestBuilder = formLogin().user("username").password("passowrd");
    mockMvc.perform(requestBuilder)
        .andDo(print())
        .andExpect(status().isOk())
        .andExpect(cookie().exists("JSESSIONID"));
    
  • 5

    在我的帖子后:Spring MockMvcBuilders Security filter

    我已经设法使用UsernamePasswordAuthenticationToken为/ oauth / token创建REST API,但我没有设法为我的受保护资源创建测试(在运行的服务器上它工作正常) . 你能告诉我们你的REST界面吗?

相关问题