简体   繁体   English

从 Spring 引导 Cucumber 测试中的属性文件动态更改值

[英]Dynamically change value from a property file in Spring Boot Cucumber test

I have a Spring Boot application in which a specific bean (MyClass) gets a @Value annotated property whose value is defined in application.properties file:我有一个 Spring 引导应用程序,其中特定的 bean (MyClass) 获得一个 @Value 注释属性,其值在application.properties文件中定义:

@Component
public class MyClass {
    
  private String type;

  public MyClass(@Value("${type}") String type) { 
    this.type=type;
  }

  public String doSomething () {...} 
}

application.properties file includes the following: type=typeA application.properties文件包括以下内容: type=typeA

The testing is done using Cucumber, and I would like to test the behavior of the method MyClass.doSomthing when the value of type is not typeA but typeB , so I thought about doing the following:测试是使用 Cucumber 完成的,我想在type的值不是typeA而是typeB时测试MyClass.doSomthing方法的行为,所以我考虑执行以下操作:

The scenario in the *.feature file will start like this: *.feature文件中的场景将像这样开始:

Scenario: Validating doSomething when type is B
    Given The value of type is typeB
    Then Validate doSomething 

in the *StepDef file - the implementation of the Given step should somehow change the value of type to typeB , so that the flow of MyClass.doSomthing will process typeB :*StepDef文件中 - Given步骤的实现应该以某种方式将type的值更改为typeB ,以便MyClass.doSomthing的流程将处理typeB

@Given("The value of type is typeB")
public void changeTypeToB() {
    ...
}

My question is: How do I set the value of type to typeB (in the method changeTypeToB ) considering the fact the during the test the Spring profile is the default one, hence the initial value of type is typeA ?我的问题是:考虑到在测试期间 Spring 配置文件是默认配置文件的事实,我如何将type的值设置为typeB (在方法changeTypeToB中),因此type的初始值为typeA

Thanks!谢谢!

Dino迪诺

You are effectively trying to change a configuration value after the Spring application has already started.在 Spring 应用程序已经启动之后,您实际上是在尝试更改配置值。

This generally requires starting a new application context and in Cucumber terms this means starting a separate test suite.这通常需要启动一个新的应用程序上下文,在 Cucumber 术语中,这意味着启动一个单独的测试套件。

You would organize this like so:你会这样组织:

package com.example.stepdefinitions;

import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
import org.junit.runner.RunWith;

@RunWith(Cucumber.class)
@CucumberOptions(
  extraGlue = "com.example.app.config.typea"
)
public class RunCucumberTestTypeA {

}

And:和:

package com.example.stepdefinitions;

import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
import org.junit.runner.RunWith;

@RunWith(Cucumber.class)
@CucumberOptions(
  extraGlue = "com.example.app.config.typeb"
)
public class RunCucumberTestTypeB {

}

Then use the context configuration to override the properties:然后使用上下文配置覆盖属性:

package com.example.app.config.typeb;

@CucumberContextConfiguration
@SpringBootTest(properties = {
        "com.example.value=Hello", 
        "com.example.value2=World"
})
public class CucumberTestContextConfiguration {

}

Or enable a profile and put your properties in application-type-b.yml :或者启用配置文件并将您的属性放入application-type-b.yml

package com.example.app.config.typeb;

@CucumberContextConfiguration
@SpringBootTest
@ActiveProfiles("type-b")
public class CucumberTestContextConfiguration {

}

As a sanity check you can then verify if the right configuration is used in the The value of type is typeB step.作为健全性检查,您可以验证在The value of type is typeB步骤中是否使用了正确的配置。

This is quite a bit of setup though.这是相当多的设置。 You can also create a new instance of MyClass that isn't managed by the spring application context and run your tests on that.您还可以创建不受 spring 应用程序上下文管理的MyClass的新实例并在其上运行测试。

@Given("The value of type is typeB")
public void changeTypeToB() {
    testInstance = new MyClass("typeB")
}
@Then("validate doSomething")
public void changeTypeToB() {
    testInstance.doSomething()
    // validate test instance did something
}

Finally you may want to reconsider your design.最后,您可能需要重新考虑您的设计。 It sounds like typeB could be a feature toggle (because you want to change it at runtime) in which case using @Value wouldn't be the right approach.听起来typeB可能是一个功能切换(因为您想在运行时更改它)在这种情况下使用@Value将不是正确的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM