如何将 JUnit TemporaryFolder @Rule 与 Spring @Value 属性一起使用?

Posted

技术标签:

【中文标题】如何将 JUnit TemporaryFolder @Rule 与 Spring @Value 属性一起使用?【英文标题】:How to use JUnit TemporaryFolder @Rule with Spring @Value properties? 【发布时间】:2020-03-01 22:46:39 【问题描述】:

我可以在junit 测试中生成TemporaryFolder,并将该文件夹用作@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 文件夹。但是怎么做呢?

【问题讨论】:

【参考方案1】:

一种可能的解决方案是通过 setter 将值注入 path(但这会强制更改被测类)或通过 Spring 的 ReflectionTestUtils 像这样:

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

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

【讨论】:

【参考方案2】:

我可以通过@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());
        
    

【讨论】:

以上是关于如何将 JUnit TemporaryFolder @Rule 与 Spring @Value 属性一起使用?的主要内容,如果未能解决你的问题,请参考以下文章

如何解决“RadAsyncUpload没有在TemporaryFolder中写入文件的权限。 ......”

如何将JUnit 4测试添加到JUnit 3测试套件中

当 JUnit 5 没有 assertThat() 函数时,如何将 Hamcrest 与 JUnit 5 一起使用?

如何将 JUnit 5 与 Gradle 一起使用?

如何将JUnit测试结果写入日志文件

如何将基于 JDBC URL 的测试容器迁移到 Junit 5