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

请求范围内的豆子在cucumber的Spring测试中不起作用

岳俊晖
2023-03-14

我有一个基于Spring 4.3.28的应用程序(即不是Spring Boot!)我想把集成测试迁移到Cucumber。

我遵循了这个教程,并将其改编成普通的Spring。

到目前为止,我编写的测试工作正常(Spring上下文已初始化等),但一旦涉及请求范围的bean,它们就会停止工作:

Caused by: java.lang.IllegalStateException: No thread-bound request found: Are you
referring to request attributes outside of an actual web request, or processing a 
request outside of the originally receiving thread? If you are actually operating 
within a web request and still receive this message, your code is probably running 
outside of DispatcherServlet/DispatcherPortlet: In this case, use 
RequestContextListener or RequestContextFilter to expose the current request.

我创建了一个小样本项目,试图重现这个问题。

有一个名为AppConfig的上下文配置类:

java prettyprint-override">
@Configuration
public class AppConfig {
   @Bean
   @Scope("request“) // when this line is removed, the test succeeds
   public ExampleService exampleService() {
      return new ExampleService();
   }

   @Bean("dependency")
   @Scope("request") // when this line is removed, the test succeeds
   public String dependencyBean() {
      return "dependency bean";
   }
}

在请求范围内,将获得一个请求范围的bean,该bean由@Autow据此注入:

public class ExampleService {

  @Autowired
  @Qualifier("dependency")
  String dependencyBean;

  public String process() { return "I have a "+dependencyBean; }
}

对于测试,我有一个Spring注释的超类:

@ContextConfiguration(classes = AppConfig.class)
@CucumberContextConfiguration
@WebAppConfiguration
public class TestBase {

  @Autowired
  public ExampleService underTest;
}

还有一个简单的Spring测试,运行良好:

@RunWith(SpringRunner.class)
public class ExampleServicePlainSpringTest extends TestBase {

  @Test
  public void whenProcessingDataThenResultShouldBeReturned() {
    assertThat(this.underTest.process()).isEqualTo("I have a dependency bean");
  }

}

Cucumber测试由以下测试类存根执行:

@RunWith(Cucumber.class)
public class ExampleServiceCucumberTest extends TestBase {}

实际的cucumber步骤定义如下:

public class CucumberStepDefinitions extends TestBase {

  private String result;

  @When("I process data")
  public void iProcessData() {
    result = this.underTest.process();
  }

  @Then("the result should be returned")
  public void checkResult() {
    assertThat(result).isEqualTo("I have a dependency bean");
  }
}

这个Cucumber的功能文件位于src/test/resources目录下,与step definitions类同名:

Feature: Example

  Scenario: Example service bean returns dependency
    When I process data
    Then the result should be returned

通常,当我遇到“找不到线程绑定的请求”错误时,这是因为@WebAppConfiguration注释丢失,或者当我试图将请求范围的bean注入非请求范围的bean时。但这里不是这样。我做错了什么?

共有1个答案

阙博容
2023-03-14

我能够找出如何解决它;更新的代码在问题中链接的github存储库中。

使用SpringRunner时,请求上下文在ServletTestExecutionListener中初始化,该列表隐式添加到测试的TestExecutionListener列表中。初始化在该侦听器的beforeTestMethod()方法中进行。

然而,正如@M.P.Korsanje在评论中正确评论的那样(谢谢!),Cucumber没有测试方法,因此永远不会执行beforeTestMethod()

我的解决方案是添加一个自定义子类的ServletTestExectionListener作为一个TestExectionListener,它将beforTestClass()调用委托给beforTestmethod()

public class ClassLevelServletTestExecutionListener extends ServletTestExecutionListener {

  @Override
  public void beforeTestClass(TestContext testContext) throws Exception {
    super.beforeTestMethod(testContext);
  }

  @Override
  public void afterTestClass(TestContext testContext) throws Exception {
    super.afterTestMethod(testContext);
  }
}

示例服务cucumber测试中

@ContextConfiguration(classes = {AppConfig.class})
@CucumberContextConfiguration
@WebAppConfiguration
@TestExecutionListeners(ClassLevelServletTestExecutionListener.class)
// extend the Spring class to get the default TestExecutionListeners
public class TestBase extends AbstractJUnit4SpringContextTests {

  @Autowired
  public ExampleService underTest;
}
 类似资料:
  • 问题内容: 我想在我的应用程序中使用请求范围的bean。我使用JUnit4进行测试。如果我尝试在这样的测试中创建一个: 使用以下bean定义: 我得到: 但是我注意到他使用了AbstractDependencyInjectionSpringContextTests,它似乎在Spring 3.0中已被弃用。我目前使用Spring 2.5,但认为切换此方法以使用Docs建议的使用AbstractJUn

  • 当我尝试使用Cucumber最新版本4.7.1(即“io.cucumber”)时,使用范围报告3.0不会生成报告。我尝试了不同版本的范围报告,但仍然正确生成输出。 我尝试了Cucumber和Extent Report之间的不同组合版本,但仍然没有输出。有人可以在这里发光来提高输出。 代码: 慰问: oader.java:362NoClassDefFoundError: gherkin/format

  • 我在项目中使用了Spring、Cucumber和Junit。测试运行程序带有注释,因此在运行套件之前,它会创建一个Spring上下文。 我希望Spring将步骤定义类实例化为Springbean,这样我就可以注入依赖项并在步骤中使用它们。可以通过将类声明为来完成。 到现在为止,一直都还不错。问题是Cucumber将再次实例化步骤定义,并且不会使用Spring已经创建的bean和注入的依赖项。 有什

  • 问题内容: 为什么结果是 不: 我们不能在范围内使用指针?这是代码,我设置了一个指针,该指针指向范围循环,但是失败了。 问题答案: 该变量设置为指向,而不是slice元素。这段代码设置为指向slice元素: 游乐场的例子

  • 更改TestResource 并向QueryFactory添加 我理解使用请求范围需要。然而,当我运行它时,我得到一个异常,它告诉我 我看不出哪里出了问题。你能给我指出这个配置应该如何正确地完成吗?

  • 从WebSocketendpoint,我尝试调用单例服务。但是我无法使用来自WebSocket的请求或会话范围。 谢谢你的帮助!