让我们假设在Spring Boot应用程序中,我在application.yaml
下有一个测试src/test/resources
文件,其中包含以下属性定义:
some:
property: ${some.property}
我们还假设我的测试类如下:
@RunWith(SpringRunner.class)
@SpringBootTest
public class PortServiceTest {
@ClassRule
public static MyClassRule classRule = new MyClassRule()
@Autowired
private MyDependency dependency;
@Test
public void shouldPopulateEnvironmentWithWiremockPort() {
// test body
}
}
其中MyClassRule
有一个名为ruleValue()
的方法,该方法进行一些计算并返回给定值:
public class MyClassRule {
public int ruleValue() {
// some calculations
return value;
}
}
我想将${some.property}
的值设置为MyClassRule.ruleValue()
的返回值,然后再将依赖项注入测试并开始测试-甚至可能在初始化Spring上下文之前。
我认为我可以使用自定义测试执行监听器:
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;
}
}
}
}
但是:
${some.property}
无法解析,测试甚至没有机会执行${some.property}
。那么如何以一种优雅,透明且可重用的方式将${some.property}
的值设置为MyClassRule.ruleValue()
的返回值?
答案 0 :(得分:1)
Spring ReflectionTestUtils是基于反射的实用程序方法的集合,用于单元测试和集成测试方案。
使用ReflectionTestUtils.setField,应该能够在“ targetClass”上设置带有值的字段(在其中注入值)。
@Before
public void setup(){
ReflectionTestUtils.setField(classRule , "fieldName", value);
}