如何在运行时使用 Cucumber 而不是通过测试加载 Spring 引导应用程序上下文?

How to load Spring Boot Application Context while using Cucumber at runtime, not via tests?

我正在使用 1.5.8.RELEASE 开发 Spring 启动应用程序,它是通过 CLI 配置和 运行 的。这些参数用于以一种或多种不同方式将应用程序配置为 运行。其中一个命令是 运行 所有黄瓜功能,并使用以下命令调用:

cucumber.api.cli.Main.main(cucumberArguments);

当前传递的参数包括:featureFolder-gstepsPackage 和几个 cucumber-report 配置参数。

我希望能够通过我的 application.properties 文件或特定于配置文件的 application.properties 文件在我的 CucumberSteps*.java 文件中配置一些属性,但是我现在 运行 正在使用这些功能意味着 Spring 引导上下文未加载。


我的第一次尝试是:

@ConfigurationProperties
public class CucumberStepsFeature1 {

    @Value("${my.property}")
    private String myProperty;

    @Given("...")
    public void given() {
        // fails below
        assertNotNull(this.myProperty);
    }
}

我第二次尝试解决此问题是:

@ContextConfiguration(classes = MyMainApp.class)
@ConfigurationProperties
public class CucumberStepsFeature1 {

    @Value("${my.property}")
    private String myProperty;

    @Given("...")
    public void given() {
        // fails below
        assertNotNull(this.myProperty);
    }
}

但我收到

的错误消息
Caused by: javax.management.InstanceAlreadyExistsException: org.springframework.boot:type=Admin,name=SpringApplication

我尝试遵循 steps listed here,但无济于事。


如果能提供帮助,我将不胜感激,但我现在要注意,由于公司政策,我在这里分享的内容将非常有限。我将无法复制或粘贴任何真实的代码片段或日志。

下面是我能找到的最干净的方法来完成我想要的:

创建一个Config class 以加载您需要的Spring 应用程序属性(application.properties and/or application-${PROFILE}.properties),例如以下:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Configuration
@ConfigurationProperties
public class PropsConfig {

    @Value("${my.property}")
    private String myProperty;

    //any other properties...

    public String getMyProperty() { 
        return this.myProperty; 
    }

创建另一个 class 作为 Spring ApplicationContext 的容器。通过将此 class 放入主应用程序 class 的子包中,确保此 class 被 Spring 扫描。请参阅下面的代码:

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SpringApplicationContextContainer implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Autowired
    public SpringApplicationContextContainer(ApplicationContext applicationContext) {
        SpringApplicationContextContainer.applicationContext = applicationContext;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringApplicationContextContainer.applicationContext = applicationContext;
    }

    public static ApplicationContext getApplicationContext() {
        return SpringApplicationContextContainer.applicationContext;
    }
}

最后,在您的 CucumberSteps class 或任何其他非 Spring class 中,您可以简单地调用 SpringApplicationContextContainer.getApplicationContext();,如下所示:

public class CucumberStepsFeature1 {

    private final PropsConfig propsConfig;

    public CucumberStepsFeature1() {
        this.propsConfig = SpringApplicationContextContainer.getApplicationContext().getBean(PropsConfig.class);
    }

    @Given("...")
    public void given() {
        // passes below
        assertNotNull(this.propsConfig);
    }