Reputation: 47913
Let's assume that in a Spring Boot application, I have a test application.yaml
file under src/test/resources
that contains the following property definition:
some:
property: ${some.property}
Also let's suppose that my test class looks like this:
@RunWith(SpringRunner.class)
@SpringBootTest
public class PortServiceTest {
@ClassRule
public static MyClassRule classRule = new MyClassRule()
@Autowired
private MyDependency dependency;
@Test
public void shouldPopulateEnvironmentWithWiremockPort() {
// test body
}
}
where MyClassRule
has a method named ruleValue()
that makes some calculations and returns a given value:
public class MyClassRule {
public int ruleValue() {
// some calculations
return value;
}
}
I want to set the value of ${some.property}
to the return value of MyClassRule.ruleValue()
before the dependencies are injected to the test and the tests start -- probably even before the Spring context is initialized.
I thought I can use a custom test execution listener:
public class CustomTestExecutionListener extends AbstractTestExecutionListener {
@Override
public void beforeTestClass(TestContext testContext) throws Exception {
Class<?> testClass = testContext.getTestClass();
Field[] fields = testClass.getFields();
for (Field field : fields) {
if (field.getType() == MyClassRule.class) {
ClassRule annotation = field.getAnnotation(ClassRule.class);
if (annotation == null) {
continue;
}
MyClassRule myClassRule = (MyClassRule) field.get(testClass);
int ruleValue = myClassRule.ruleValue();
ApplicationContext context = testContext.getApplicationContext();
Environment environment = context.getEnvironment();
// how to set {some.value} in environment?
break;
}
}
}
}
but:
${some.property}
cannot be resolved${some.property}
into the environment.So how can I set the value of ${some.property}
to the return value of MyClassRule.ruleValue()
in an elegant, transparent, and reusable way?
Upvotes: 0
Views: 1620
Reputation: 769
Spring ReflectionTestUtils is a collection of reflection-based utility methods for use in unit and integration testing scenarios.
Using ReflectionTestUtils.setField, you should be able to set field (where you injecting value) with value on the "targetClass".
@Before
public void setup(){
ReflectionTestUtils.setField(classRule , "fieldName", value);
}
Upvotes: 2