如何通过Spring @Value属性使用JUnit TemporaryFolder @Rule?

时间:2019-11-05 14:25:00

标签: java spring spring-boot junit spring-boot-test

我可以在TemporaryFolder测试中生成junit,并使用该文件夹作为@Value属性的前缀吗?

@RunWith(SpringRunner.class)
@SpringBootTest
public class MyTest {
    @Rule
    public TemporaryFolder tmp = new TemporaryFolder();


    @Autowired
    private MyService service;

    @Test
    public void test()  {
        //TODO how to rewrite the application property with the tmp folder created?
        service.run();
    }
}

@Service
public class MyService {
    @Value("${my.export.path}")
    private String path;

    public void run() {
        //generates a file and exports it to @Value path
    }
}

application.properties:

my.export.path=/var/www/export.csv

我当然想将导出路径设置为生成的tmp文件夹。但是如何?

2 个答案:

答案 0 :(得分:0)

一种可能的解决方案是通过setter(但这会改变测试中的类)或通过Spring的path将值注入ReflectionTestUtils,例如:

@Test
public void test() {
  ReflectionTestUtils.setField(service, "path", tmp.getRoot().getAbsolutePath());
  service.run();
}

您还可以考虑创建一个内部配置类,该类为您提供具有所需路径的MyService bean。

答案 1 :(得分:0)

我可以用@ClassRuleApplicationContextInitializer重写ApplicationContext中的属性来解决它。虽然可行,但可能还有一些我仍然感兴趣的更好的解决方案!

@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(initializers = TemporaryFolderInitializer.class)
public class MyTest {
    @ClassRule
    public static TemporaryFolder tmp = new TemporaryFolder();

    public static class TemporaryFolderInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
        @Override
        public void initialize(ConfigurableApplicationContext applicationContext) {
            TestPropertySourceUtils.addInlinedPropertiesToEnvironment(applicationContext, "my.export.path=" + tmp.getRoot().getAbsolutePath());
        }
    }
}