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:
@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
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:
The scenario in the *.feature
file will start like this:
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
:
@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
?
Thanks!
Dino
You are effectively trying to change a configuration value after the Spring application has already started.
This generally requires starting a new application context and in Cucumber terms this means starting a separate test suite.
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
:
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.
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.
@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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.