当前位置: 首页 > 知识库问答 >
问题:

Spring Security@WithMockUser不支持cucumber测试

须捷
2023-03-14

我正在使用cucumber测试来测试我的Spring启动应用程序,启用了Spring安全。除了当我用cucumber测试一些使用Spring安全的测试时,事情运行得很好。

    @WithMockUser(username = "BROWSER", roles =
   {"BROWSER","ADMIN"})

失败。如果我像简单的jUnit测试那样隐蔽地运行它们,这些测试确实有效,但是当使用cucumber测试步骤运行时失败了。当我用cucumber测试运行同样的测试时,这个问题看起来像是Spring安全测试模拟行为没有被应用。

我的Cumber试运行课程如下

@RunWith(Cucumber.class)
@CucumberOptions(features = "src/test/resources", monochrome = true, format =
{"pretty", "html:src/main/resources/static/cucumber"})
public class CucumberTests
{

}

我还注意到,通过Maven运行

使现代化

所有测试扩展的类

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = Services.class,loader = SpringApplicationContextLoader.class)
//@IntegrationTest
@WebIntegrationTest(randomPort = true)
public abstract class AbstractIntegrationTest {

另一个不起作用的用例是使用这些注释的特性条件,如下所示

@When("^I apply a GET on (.*)$")
    @WithMockUser(username = "BROWSER", roles = { "BROWSER", "ADMIN" })
    public void i_search_with_rsql(String query) throws Throwable {
    result = mvc.perform(get(uri, query));
    }

这方面的任何帮助或解决方法。


共有3个答案

柯易安
2023-03-14

作为对Rob Winch回答的回应,我的工作使用了他的方法减去“.apply(springSecurity())”行

祁晟
2023-03-14

根据您的评论,您需要确保应用Spring安全。您可以在参考留档的设置MockMvc和Spring安全部分找到一个例子:

import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.*;

// ...

@Before
public void setup() {
    mvc = MockMvcBuilders
            .webAppContextSetup(context)
            .apply(springSecurity()) // ADD THIS!
            .build();
}
聂翼
2023-03-14

WithMockUser不适用于Cucumber。用cucumber钩代替。

WithMockUser依赖Spring的测试上下文支持中的TestExecutionListener#beforeTestMethod,但在运行Cucumber runner时不会调用它们。这是因为Cucumber运行的场景由步骤组成,而不是标准的JUnit测试方法。

选项1-安全上下文钩子。您可以使用钩子设置安全上下文,例如:

@ActiveProfiles("test")
@SpringBootTest(classes = MyServer.class)
@AutoConfigureMockMvc
@AutoConfigureRestDocs
@AutoConfigureCache
public class MyServerContextHooks {

  @Before
  public void onBeforeScenario(final Scenario scenario) {
    // This method does nothing - context setup is done with annotations
  }
}

场景注释示例:

@WithAdminUser
Scenario: Run action as admin
    ...

在场景中使用注释的示例钩子:

public class TestUserHooks {

  @Before("@WithAdminUser")
  public void setupAdminUser() {
    SecurityContextHolder.getContext().setAuthentication(
            new UsernamePasswordAuthenticationToken(
                "admin",
                "N/A",
                createAuthorityList("admin")));         
  }
}

选项2-身份验证步骤。另一种方法是使用特殊步骤将用户提供到mockMvc:

Scenario: Run action as admin
    Given I am logged in as admin
    ...

stepdef示例:

public class SecurityTestSteps {

  @Autowired
  private MockMvcGlue mockMvc;

  @Autowired
  private OAuth2Mocks oauth2Mocks;

  @Autowired
  private TestUsers users;

  /**
   * Provides a one of predefined role-based authentications for the current request.
   */
  @Given("^I am logged in as (admin|editor|user)$")
  public void given_UserIsAuthenticatedWithRole(final String role) {
    switch (role) {
      case "admin":
        mockMvc.request().with(authentication(oauth2Mocks.auth(users.admin())));
        break;
      case "editor":
        mockMvc.request().with(authentication(oauth2Mocks.auth(users.edtior())));
        break;
      default:
        throw new CucumberException("Unsupported role <" + role + ">");
    }
  }
}
 类似资料:
  • 我正在为我的应用程序编写单元测试,我在服务内部执行的步骤之一是从SpringSecurityContext获取当前经过身份验证的用户。 我知道,如果我想模拟Spring Security Authentication,我可以使用@SusMockUser,但它对我不起作用,因为当测试方法到达getAuthentication()方法调用时,它总是返回null... 我已经搜索了很多问题和博客帖子,但

  • 尽管我的测试方法被@WithMockUser注释,但我仍然被拒绝访问。为什么这在集成测试中不起作用?使用@webappconfiguration和mockmvc进行测试一切都很好。

  • 本文向大家介绍SpringSecurity 测试实战,包括了SpringSecurity 测试实战的使用技巧和注意事项,需要的朋友参考一下 引言 试题管理系统的安全模块使用Spring Security,代码从原华软仓库移植,在移植的过程中,发现原测试编写的不好,遂在新系统中对安全模块测试进行了重构。 Spring 测试 添加@SpringBootTest注解,意为这是一个基于SpringBoot

  • 我试图使用JUnit 5使用Java测试Android Studio中活动内部的函数,但是,我得到了以下错误: 我正在关注在线教程,但没有一个在活动上实现测试,相反,它们是main中的简单类。 这是我的测试代码: 我很确定语法的某些部分不正确,但我找不到有关如何修复它的指导。 getRandomInteger() 函数只生成一个随机整数。它应该返回 false,除非我得到“幸运”并得到预期的数字。

  • 你可以为特定 variant 运行 lint,例如 ./gradlew lintRelease,或为所有 variants 运行(./gradlew lint),这种情况下会生成一份包含特定版本存在的问题的详细报告。你可以像下面的代码片段那样通过配置 lintOptions 节点来配置 lint。一般只能配置小部分选项,查看 DSL reference 了解所有可修改的选项。 android {

  • 5.5 Lint支持 从0.7.0版本之后,你可以为一个特定的变种版本运行 lint ,也可以为所有变种版本都运行.在这种情况下,它会产生一个报告指出给定的变种版本的问题. 你可以像下面一样通过 lintOptions 自定义 lint .一般情况下,你只需要配置其中的一部分.以下是展示所有可用的 lint 配置项. android { lintOptions { // s