@WebMvcTest需要@Import(SecurityConfig.class)来启用SpringSecurity

Pie*_*nes 3 spring-security spring-boot mockmvc spring-boot-test

首先,重要的是要指定应用程序已经部署并且我们的 spring 安全配置有效。如果未经身份验证的用户尝试访问 API 的任何端点,则会返回 401 Unauthorized。

@WebMvcTest接下来,在这个示例示例中,我想使用和 来测试控制器spring security

@WebMvcTest(EmployeeController.class)   
@Import(SecurityConfig.class)
class EmployeeControllerTest {

    @Autowired
    private WebApplicationContext ctx;

    protected MockMvc mvc;

    @MockBean
    private EmployeeService service;

    @BeforeEach
    public void setUp() {
        this.mvc = MockMvcBuilders
                .webAppContextSetup(ctx)
                .apply(springSecurity())
                .build();
    }

    @Test
    void unauthorized_role_should_return_401() {

       mvc.perform(get("/employees/1").accept(MediaType.APPLICATION_JSON)
            .with(SecurityMockMvcRequestPostProcessors.user("manager").roles("UNKNOWN")))
            .andExpect(status().isUnauthorized())
    }
}
Run Code Online (Sandbox Code Playgroud)

这段代码有效,但我不明白为什么需要将该SecurityConfig类导入到测试类中。事实上,如果我删除@Import,mockMvc返回 200。但是,我发现的每个示例项目都Github只是使用@WebMvcTest,即使该项目有一个SecurityConfig

Ken*_*han 5

使用时不需要配置额外的东西来启用 Spring Security,@WebMvcTest因为@WebMvcTest会自动启用它。

但是,如果您通过创建自己的 bean 来自定义 spring-security,则仍然必须为测试定义这些自定义 bean,以使自定义生效。@Import是定义这些bean的方法之一。通过将它们的配置合并到一个文件中SecurityConfig,它可以使您的测试用例保持干燥,因为如果测试用例需要使用安全性内容进行测试,它只需要导入它,SecurityConfig而不是为每个测试重复执行相同的配置。

因此,这是一个特定于应用程序的代码设计决策,因此并非每个项目都具有相同类型的设置是正常的。