简体   繁体   English

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

[英]Unit Testing /login in Spring MVC using MockMvc

I have a very simple REST application created using Spring MVC. 我有一个使用Spring MVC创建的非常简单的REST应用程序。 (Code is available at GitHub .) It has a simple WebSecurityConfigurer as follows: (代码可在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);
}

When I run the application, both the custom controllers and the login/logout pages work without a problem. 当我运行该应用程序时,自定义控制器和登录/注销页面都可以正常工作。 I can even unit test /user/new via MockMvc . 我什至可以通过MockMvc /user/new进行单元测试 However, when I try to test /login with the following function 但是,当我尝试使用以下功能测试/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"));
}

it fails as follows: 它失败,如下所示:

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>

But I am pretty user POST to /login is working when I run the application instead of test. 但是我很不错,当我运行应用程序而不是测试时,用户到/login POST工作正常。 Further, when I try make a GET or HEAD request (as suggested in the Headers = {Allow=[HEAD, GET]} line of the logs), this time I receive a 404. Any ideas about what is going on and how can I fix it? 此外,当我尝试发出GETHEAD请求(如日志的Headers = {Allow=[HEAD, GET]}行中的建议)时,这次我收到404。有关正在进行的事情以及如何解决的任何想法我修理它?

I noticed the github link now. 我注意到了github链接。 I believe you need to configure security filter also for your tests. 我相信您还需要为测试配置安全过滤器。 Something like 就像是

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

Some additional settings might be necessary, you might check http://www.petrikainulainen.net/programming/spring-framework/integration-testing-of-spring-mvc-applications-security/ for inspiration. 可能需要一些其他设置,您可以检查http://www.petrikainulainen.net/programming/spring-framework/integration-testing-of-spring-mvc-applications-security/以获取灵感。

You could use spring security testing classes to test form based login. 您可以使用spring安全测试类来测试基于表单的登录。 You need to do the following to test form based login. 您需要执行以下操作来测试基于表单的登录。

Maven dependency: Maven的依赖:

<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"));

Following my post here: Spring MockMvcBuilders Security filter 在这里关注我的帖子: Spring MockMvcBuilders安全过滤器

I have manage to create REST API with UsernamePasswordAuthenticationToken for /oauth/token but I didn't manage to create the test for my protected resource (on running server it work fine). 我已经设法使用UsernamePasswordAuthenticationToken为/ oauth / token创建REST API,但是我没有为受保护的资源创建测试(在运行的服务器上运行正常)。 Could you show us your REST interface ? 您能告诉我们您的REST界面吗?

Testing SpringSession, I achieved to get the session cookie and saving session to an embedded Redis doing this: 通过测试SpringSession,我实现了获取会话cookie并将会话保存到嵌入式Redis的目的:

@Autowired
private SessionRepositoryFilter<?> springSessionRepositoryFilter;
...

@Before
public void setup() {
    mvc = MockMvcBuilders
        .webAppContextSetup(context)
        .addFilters(springSessionRepositoryFilter)
        .apply(springSecurity())
        .build();
}

Hope it helps. 希望能帮助到你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM