首页 > 解决方案 > 如何测试受保护的 Spring Controller

问题描述

我目前有一个使用 Spring Boot 2、Spring MVC、Spring Data/JPA 和 Thymeleaf 构建的应用程序。

我正在编写一些单元/集成测试,并且我想测试控制器,该控制器由 SpringSecurity 保护,该数据库由注册用户提供支持。

在这里测试它的最佳方法是什么?我没有成功地尝试过其中一些,比如使用@WithMockUser.

编辑:只是提醒我没有测试@RestControllers。我直接@Controller在我的测试类上注入 a 并调用它的方法。如果没有 Spring Security,它就可以正常工作。

一个例子:

@Controller
public class SecuredController {
  @GetMapping("/")
  public String index() {
    return "index";
  }
}

/路径由 Spring Security 保护,通常会重定向到/login以对用户进行身份验证。

我的单元测试看起来像这样:

@WebMvcTest(controllers = SecuredController.class)
class SecuredControllerTest {

  @Autowired
  private SecuredController controller;

  @Autowired
  private MockMvc mockMvc;

  @Test
  @WithMockUser(username = "user", password = "pass", roles = {"USER"})
  public void testAuthenticatedIndex() throws Exception {
    mockMvc.perform(get("/"))
        .andExpect(status().isOk())
        .andDo(print());
  }
}

我得到的第一个错误是要求我注入我的 UserDetailsS​​ervice 实现,这是我想避免的。但是,如果我确实注入了服务,则测试可以工作,但返回 404 而不是 200。

有任何想法吗?

标签: javaspringspring-bootspring-securityintegration-testing

解决方案


您将需要通过导入您的WebSecurityConfigurerAdapter类将您的安全配置添加到 Spring 上下文中。

@WebMvcTest(controllers = SecuredController.class)
@Import(SecuredControllerTest.Config.class)
class SecuredControllerTest {

   @Configuration
   @EnableWebSecurity
   static class Config extends MyWebSecurityConfigurerAdapter {
      @Autowired
      public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
          auth.inMemoryAuthentication().withUser("user").password("pa$$").roles("USER");
          auth.inMemoryAuthentication().withUser("admin").password("pa$$").roles("ADMIN");
      }
   }

   ...
}

嵌入式static class Config只是为了改变我们从哪里获取用户,在这种情况下一个inMemoryAuthentication就足够了。


推荐阅读