是否可以仅使用 junit 5 将 spring 安全配置加载到我的测试中?

Posted

技术标签:

【中文标题】是否可以仅使用 junit 5 将 spring 安全配置加载到我的测试中?【英文标题】:Is it possible to only load spring security config to my test with junit 5? 【发布时间】:2022-01-21 23:07:44 【问题描述】:

当我检查了我找到的文档this 时,我想使用基于方法的安全性对我的控制器安全性进行单元测试,但它使用了@RunWith,而且它似乎并没有只加载安全配置。

我想做什么: 加载我的安全配置

@ContextConfiguration(classes = SecurityConfigImpl.class)
public class PeopleGQLApiSecutiryTest 
    private final PersonService personService = mock(PersonService.class);
    private final PeopleGQLApi peopleGQLApi = new PeopleGQLApi(personService);

    @Test
    @WithAnonymousUser
    void itShouldCreateNewPerson() 
        when(personService.createNewPerson(any(Person.class))).thenReturn(new Person());
        // this should fail!
        peopleGQLApi.createPerson(
                Person.LevelEnum.WEAK,
                // rest of the arguments
        );
    

这个应该失败(通过抛出一个期望或类似的东西),因为 create person 是一个安全的函数,带有ROLE_ADMIN

注意:这是一个 GraphQL 突变

    @MutationMapping("createPerson")
    @Secured("ROLE_ADMIN")
    public Person createPerson(
       @Argument("level") Level level,
             // rest of the arguments
    ) 
             // method implementation
      

我不能使用完全成熟的 @SpringBootTest,因为我还必须提供 mongodb 配置,这超出了本测试的范围。

【问题讨论】:

【参考方案1】:

我认为您正在寻找的词是@WithMockUser

您可以使用 @WithMockUser(authorities = "ROLE_ADMIN") 之类的东西来模拟具有此角色的用户

还可以使用 Spring Security Context 进行更多调整

SecurityContext securityContext = SecurityContextHolder.createEmptyContext();
securityContext.setAuthentication(new UsernamePasswordAuthenticationToken("username", "password"));
SecurityContextHolder.setContext(securityContext);

您可以将任何权限添加到您的安全上下文中或读取它们。

最好将它们添加到 securityUtil 类中,以便在多种情况下使用。

请确保您有一个断言来验证测试用例中未经授权的请求

【讨论】:

以上是关于是否可以仅使用 junit 5 将 spring 安全配置加载到我的测试中?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以使用 Spring ApplicationContext 中的 bean 参数化 JUnit Jupiter 测试?

如何使用 Gradle 和 JUnit 5 仅运行特定测试?

是否有任何特殊配置可以将 SpringRunner 与 junit5 一起使用?

仅用于 Spring 应用程序中的 JUnit 测试的单独数据库

将 JUnit JPA 测试从 Spring 2.5.5 迁移到 Spring 3.0.4

Spring @DataJpaTest 与 JUnit 5