Search code examples
javaspringjunit

How to use non-static @TempDir with custom @ConfigurationProperties during testing


I am working on a Spring Batch application which processes image files, where the path to the images is configurable using application.yml:

files:
    image-path: /var/images

I'm trying to use a non-static field annotated with @TempDir in one of my Spring Boot integration tests, so that I get a new temporary folder for each test:

@SpringBatchTest
@SpringBootTest
@SpringJUnitConfig(classes = ImageBatchJobApplication.class)
class ImageBatchJobTests {

    @TempDir
    private Path imagePath;

    ...
}

The problem is that I somehow need to pass this temporary folder path to my custom @ConfigurationProperties class:

@ConfigurationProperties(prefix = "files")
public record MyConfiguration(String imagePath) { }

I tried to use a @DynamicPropertySource where I would add the temporary directory to the registry:

@DynamicPropertySource
private static void testProperties(DynamicPropertyRegistry registry) {
    registry.add("files.image-path", imagePath::toString);
}

but of course from within a static method I can not access the non-static imagePath field. I thought about using a custom ApplicationCOntextInitializer, however there I would run into the same problem of how to access the instance variable. Does anybody have an idea how I could pass my @TempDir path to the MyConfiguration before each test tun?


Solution

  • One option is to inject the configuration class annotated with @ConfigurationProperties in the beforeEach method and update the value there:

    @DirtiesContext
    @SpringBatchTest
    @SpringBootTest
    @SpringJUnitConfig(classes = ImageBatchJobApplication.class)
    class ImageBatchJobApplicationTests {
    
        @TempDir
        private Path imagePath;
    
        @BeforeEach
        public void setup(@Autowired MyConfiguration config) {
            config.setImagePath(imagePath.toString());
        }
    }