Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring Security@WithMockUser不适用于cucumber测试_Java_Spring_Spring Security - Fatal编程技术网

Java Spring Security@WithMockUser不适用于cucumber测试

Java Spring Security@WithMockUser不适用于cucumber测试,java,spring,spring-security,Java,Spring,Spring Security,我使用cucumber测试来测试启用了spring安全性的spring boot应用程序。除了使用cucumber测试运行我的测试套件外,一切正常。一些使用spring安全性的测试例如 @WithMockUser(username = "BROWSER", roles = {"BROWSER","ADMIN"}) 失败。如果我将这些测试作为简单的junit测试在隔离状态下运行,那么它们确实可以工作,但在使用cucumber测试步骤运行时失败。 当我对cucumber测试运行相同的

我使用cucumber测试来测试启用了spring安全性的spring boot应用程序。除了使用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以
false
运行时也可以使用相同的方法。如果未选中此选项,Maven触发的测试用例运行也会失败

更新

AbstractIntegrationTest类所有测试都将扩展

@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));
    }

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

根据您的评论,您需要确保应用Spring安全性。您可以在参考文档的中找到这方面的示例:

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

// ...

@Before
public void setup() {
    mvc = MockMvcBuilders
            .webAppContextSetup(context)
            .apply(springSecurity()) // ADD THIS!
            .build();
}

WithMockUser
不适用于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")));         
  }
}
在场景中使用注释的示例钩子:

@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
    ...
步骤定义示例:

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 + ">");
    }
  }
}
public类SecurityTestSteps{
@自动连线
私有MockMvcGlue mockMvc;
@自动连线
私有OAuth2Mocks OAuth2Mocks;
@自动连线
私人测试用户;
/**
*为当前请求提供预定义的基于角色的身份验证之一。
*/
@给定(^I以(管理员|编辑|用户)$身份登录)
public void给定_UserIsAuthenticatedWithRole(最终字符串角色){
交换机(角色){
案例“管理”:
mockMvc.request().with(身份验证(oauth2Mocks.auth(users.admin()));
打破
案例“编辑”:
mockMvc.request().with(身份验证(oauth2Mocks.auth(users.edtior()));
打破
违约:
抛出新CucumberException(“不支持的角色”);
}
}
}

要让WithMockUser工作,Spring安全应用程序必须在与测试相同的进程/线程上运行。是这样吗?@Robja让我检查一下,当我运行我应用程序中的所有测试时,没有Cucumber,这些测试运行正常。是Cucumber测试运行使我的测试单独运行吗。已使用ABstractIntegrationTest类更新了我的问题摘要。我的所有测试用例都是从中继承的。@RobWinch是否有withMockUser的替代方案来模拟,因为如果您将then-in用于cucumber测试,则这些选项似乎也不起作用@当(^I应用GET-on(.*)$)
@withMockUser(username=“BROWSER”,roles={“BROWSER”,“ADMIN”})public void i_search_with_rsql(字符串查询)抛出可丢弃的{result=mvc.perform(get(uri,query))}
如何设置MockMvc实例(即mvc变量)?@RobWinch目前我正在使用cucumber@Before注释
@cumber.api.java.Before public void setUp(){this.mvc=MockMvcBuilders.webAppContextSetup(context.build();}
我想上面的方法适用于模拟springsecuritychain,但现在我必须将模拟角色作为
mvc.perform(get(uri,query).with(getAdminRole())放入get请求中
虽然注释@WithMockUser仍然不起作用,但无论如何,我已经找到了一个解决方法,并且测试通过了:)谢谢