Skip to content
Tools to define a dynamic property in Spring Boot integration tests.
Java
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
src
.gitignore
.travis.yml
README.adoc
pom.xml

README.adoc

Spring Dynamic Property

Build Status badge

Tools to define a dynamic property in Spring Boot integration tests.

How to set a property value in tests by the standard spring mechanics

In the Spring Framework we have an annotation TestPropertySource which allows define a final property value:

@SpringBootTest
@ExtendWith(SpringExtension.class)
@TestPropertySource(properties = "my.variable=12345")
class FinalPropertyValueTest {

	@Value("${my.variable}")
	private String variable;

	@Test
	void testVariableValue() {
		assertThat(variable).isEqualTo("12345");
	}
}

On this way we have a small limitation - we cannot define a dynamic value of properties in this annotation, even use of a static method not allowed here.

How to define a dynamic value of properties in tests

spring-dynamic-property supports an ability to define a dynamic value of properties and declare static property provider methods in your test class.

All that you need to use the spring-dynamic-property is the next dependency:

<dependency>
    <groupId>com.jupiter-tools</groupId>
    <artifactId>spring-dynamic-property</artifactId>
    <version>0.1</version>
</dependency>

Let’s look at the simple example of using a dynamic value in properties:

Simple example

@SpringBootTest
@ExtendWith(SpringExtension.class)
class SimpleTest {

	@DynamicTestProperty
	private static TestPropertyValues props() {
		return TestPropertyValues
				.of("variable=" + (int) Math.sqrt(64));
	}

	@Value("${variable}")
	private int variable;

	@Test
	void testSqrt() {
		assertThat(variable).isEqualTo(8);
	}
}

Example with the using of TestContainers

A most primary case to use dynamic properties is a TestContainers initialization in your spring-boot applications.

Let’s consider an example of initialization standard spring-boot properties after start Redis test container:

@SpringBootTest
@Testcontainers
@ExtendWith(SpringExtension.class)
class RedisTestcontainersTest {

    private static final Integer REDIS_PORT = 6379;

    @Container
    private static GenericContainer redis = new GenericContainer("redis:latest")
            .withExposedPorts(REDIS_PORT);

    @DynamicTestProperty
    private static TestPropertyValues props() {
        return TestPropertyValues.of("spring.redis.host=" + redis.getContainerIpAddress(),
                                     "spring.redis.port=" + redis.getMappedPort(REDIS_PORT));
    }

    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    void readWriteValueByRedisTemplate() {
        String key = "test";
        String value = "sabracadabra";
        // Act
        redisTemplate.opsForValue().set(key, value);
        // Assert
        assertThat(redisTemplate.opsForValue().get(key)).isEqualTo(value);
    }
}

Include dynamic property in meta-annotations

If you need to make you own annotation with dynamic property declaration then you can specify a file with @DynamicProperty methods by the using of @IncludeDynamicProperty annotation as you can see in the example below:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@IncludeDynamicProperty(DynamicPropertyHolder.class)
public @interface AnnotationWithDynamicProperty {

}

the file with dynamic properties:

public class DynamicPropertyHolder {

    @DynamicTestProperty
    private static TestPropertyValues property(){
        return TestPropertyValues.of("key=12345");
    }
}

and now you can use this annotation in your tests to set this property:

@SpringBootTest
@AnnotationWithDynamicProperty
class MetaAnnotationTest {

    @Value("${key}")
    private String key;

    @Test
    void checkPropertyValueInjectInAnnotation() {
        assertThat(key).isEqualTo("12345");
    }
}
You can’t perform that action at this time.