gpt4 book ai didi

spring-boot - Spring Boot 主作用域中的 cucumber : Autowire not working

转载 作者:行者123 更新时间:2023-12-03 20:50:08 26 4
gpt4 key购买 nike

处理这篇文章:Cucumber: no backend found when running from Spring Boot jar

我试图让 Cucumber 在实时 Spring Boot 应用程序中完全工作。我目前有一个 POC 应用程序,使用上述帖子的代码创建一个 Cucumber Runtime,它运行一个简单的 Feature/Steps 类,并引用了一个 Bean:
服务:

public void testFeature(){
RuntimeOptions runtimeOptions = new RuntimeOptions(new ArrayList<String>(asList("--glue", "org.bdd.poc", "--no-dry-run", "--monochrome", "classpath:features")));
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
ResourceLoader resourceLoader = new CustomMultiLoader(classLoader);
ClassFinder classFinder = new ResourceLoaderClassFinder(resourceLoader, classLoader);
Runtime runtime = new Runtime(resourceLoader, classFinder, classLoader, runtimeOptions);
try {
runtime.run();
} catch (IOException e) {
e.printStackTrace();
}
}
演示步骤:
(no class annotation)
public class DemoSteps {

@Autowired
private MyBean bean;

public DemoSteps(){
System.err.println("STEP INIT");
}

@Given("a proof of concept")
public void givenAPOC(){

}

@When("doing a demo")
public void whenDemo(){

}

@Then("it should talk to a bean")
public void thenItShouldTalkToABean(){
this.bean.poke();
}
}
bean 角,扁 bean :
@Component
public class MyBean {
public void poke(){
System.err.println("I'VE BEEN POKED! THE PAIN!");
}
}
DemoSteps.java 类将此作为一个类字段,@Autowired 就位,但它既没有填充 bean 引用,也没有在 DemoSteps 构建后失败。我通过调试看到有 spring bean 工厂被用来创建 Steps 实例,但没有涉及 Autowiring 。我猜测为了将一些连接应用到主要的 SpringContext 在于:
  • 一个合适的后端实现
  • 合适的 Glue 实现

  • 我知道使用空手道框架可以完成类似的事情,但我还没有找到允许建立连接的原因。
    当前使用 Spring Boot 2.3.0 和 Cucumber 2.4.0,根据“spring-boot-maven-plugin”配置解压。

    最佳答案

    我的解决方案不完全是后端,而是其中的一部分。 cucumber-spring依赖的实现是 cucumber.api.java.ObjectFactory .此类充当创建 Step 类的访问点,这些类包含 @Given/@When/等等。有一个“测试类”可以维护这一点。但是,我采用了与主应用程序上下文 AnnotationApplicationContext 不同的方式创建“子”应用程序上下文。特别是处理@Autowired注释。
    无论如何,这是代码:
    服务:

    Service Method:
    @Autowired(required = false)
    private List<LiveTestEventHandler> testEventHandlerList;
    @Autowired
    private ApplicationContext applicationContext;

    public void testFeature(){
    RuntimeOptions runtimeOptions = new RuntimeOptions(new ArrayList<String>(asList("--glue", "org.bddynamic.poc", "--no-dry-run", "--monochrome", "classpath:features")));
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    ResourceLoader resourceLoader = new CustomMultiLoader(classLoader);
    ClassFinder classFinder = new ResourceLoaderClassFinder(resourceLoader, classLoader);
    ObjectFactory objectFactory = new LiveTestFactory(this.applicationContext);
    JavaBackend javaBackend = new JavaBackend(objectFactory,classFinder);
    Runtime runtime = new Runtime(resourceLoader, classLoader, asList(javaBackend), runtimeOptions);
    for(LiveTestEventHandler handler : this.testEventHandlerList){
    runtime.getEventBus().registerHandlerFor(handler.getSupportedClass(),handler);
    }
    try {
    runtime.run();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }

    定制工厂:
    (真的是 cucumber-spring:runtime.java.spring.SpringFactory.java的删减版)
    public class LiveTestFactory implements ObjectFactory {
    private final DefaultListableBeanFactory beanFactory;
    private final GenericApplicationContext applicationContext;
    private final Collection<Class<?>> stepClasses = new HashSet();
    public LiveTestFactory(ApplicationContext applicationContext){
    AnnotationConfigApplicationContext childContext = new AnnotationConfigApplicationContext();
    childContext.setParent(applicationContext);
    this.applicationContext = childContext;
    this.beanFactory = (DefaultListableBeanFactory) this.applicationContext.getBeanFactory();
    }
    @Override
    public void start() {
    ((ConfigurableApplicationContext)this.applicationContext).registerShutdownHook();
    beanFactory.registerScope(LiveTestScope.NAME, new LiveTestScope());
    for(Class stepClass : this.stepClasses){
    this.registerStepClassBeanDefinition(this.beanFactory, stepClass);
    }
    this.applicationContext.refresh();
    this.applicationContext.start();
    }
    @Override
    public void stop() {
    LiveCodeContext.getInstance().stop();
    this.applicationContext.stop();
    }
    @Override
    public boolean addClass(Class<?> stepClass) {
    if (!this.stepClasses.contains(stepClass)) {
    this.stepClasses.add(stepClass);
    }
    return true;
    }
    @Override
    public <T> T getInstance(Class<T> type) {
    try {
    return this.applicationContext.getBean(type);
    } catch (BeansException var3) {
    throw new CucumberException(var3.getMessage(), var3);
    }
    }
    private void registerStepClassBeanDefinition(DefaultListableBeanFactory beanFactory, Class<?> stepClass) {
    BeanDefinitionRegistry registry = beanFactory;
    BeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(stepClass).setScope(LiveTestScope.NAME).getBeanDefinition();
    registry.registerBeanDefinition(stepClass.getName(), beanDefinition);
    }
    }

    关于spring-boot - Spring Boot 主作用域中的 cucumber : Autowire not working,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63272323/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com