Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Appropriate usage of TestPropertyValues in Spring Boot Tests

I came across TestPropertyValues, which is briefly mentioned in the Spring Boot docs here: https://github.com/spring-projects/spring-boot/blob/2.1.x/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc#testpropertyvalues

It's also mentioned in the Migration Guide here: https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Migration-Guide#environmenttestutils

Both examples show an environment variable to apply the properties to, but there's no other documentation that I could find.

In my tests the property setting comes too late to affect the property injection (via @Value) for a Spring Bean. In other words, I have a constructor like this:

  public PhoneNumberAuthorizer(@Value("${KNOWN_PHONE_NUMBER}") String knownRawPhoneNumber) {
    this.knownRawPhoneNumber = knownRawPhoneNumber;
  }

Since the above constructor is called before the test code has a chance to run, there's no way change the property via TestPropertyValues in the test before it's used in the constructor.

I understand that I can use the properties parameter for @SpringBootTest, which updates the environment before beans get created, so what's the appropriate usage of TestPropertyValues?

like image 295
Ted M. Young Avatar asked Feb 16 '19 01:02

Ted M. Young


People also ask

What is the purpose of @SpringBootTest?

The @SpringBootTest annotation is useful when we need to bootstrap the entire container. The annotation works by creating the ApplicationContext that will be utilized in our tests. We can use the webEnvironment attribute of @SpringBootTest to configure our runtime environment; we're using WebEnvironment.

Which of these is used for writing test cases in spring boot?

The @Profile(“test”) annotation is used to configure the class when the Test cases are running. Now, you can write a Unit Test case for Order Service under the src/test/resources package.

Which annotation can be used to run quick unit tests?

The @SpringBootTest annotation can be used to run quick unit tests in Spring Boot.

What does SpringBootTest annotation do?

The @SpringBootTest annotation loads the complete Spring application context. In contrast, a test slice annotation only loads beans required to test a particular layer. And because of this, we can avoid unnecessary mocking and side effects.

What is testentitymanager in Spring Boot?

The Spring Boot TestEntityManager is an alternative to the standard JPA EntityManager that provides methods commonly used when writing tests. EmployeeRepository is the component that we are going to test. Now let's write our first test case:

How do I use @testpropertysource in Spring Boot?

How to Use @TestPropertySource Let's imagine we're using the value of a property by injecting it using the @Value Spring annotation: We'll then use the @TestPropertySource class-level annotation to define a new configuration source and override the value of that property:

What is integration testing in Spring Boot?

Integration Testing With @SpringBootTest As the name suggests, integration tests focus on integrating different layers of the application. That also means no mocking is involved. Ideally, we should keep the integration tests separated from the unit tests and should not run along with the unit tests.

What is the Spring Boot starter test dependency?

The spring-boot-starter-test is the primary dependency that contains the majority of elements required for our tests. The H2 DB is our in-memory database. It eliminates the need for configuring and starting an actual database for test purposes.


1 Answers

TestPropertyValues isn't really designed with @SpringBootTest in mind. It's much more useful when you are writing tests that manually create an ApplicationContext. If you really want to use it with @SpringBootTest, it should be possible to via an ApplicationContextInitializer. Something like this:

@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(initializers = PropertyTest.MyPropertyInitializer.class)
public class PropertyTest {

    @Autowired
    private ApplicationContext context;

    @Test
    public void test() {
        assertThat(this.context.getEnvironment().getProperty("foo")).isEqualTo("bar");
    }

    static class MyPropertyInitializer
            implements ApplicationContextInitializer<ConfigurableApplicationContext> {

        @Override
        public void initialize(ConfigurableApplicationContext applicationContext) {
            TestPropertyValues.of("foo=bar").applyTo(applicationContext);
        }

    }

}

Spring Boot's own test make use of TestPropertyValues quite a bit. For example, applyToSystemProperties is very useful when you need to set system properties and you don't want them to be accidentally left after the test finishes (See EnvironmentEndpointTests for an example of that). If you search the codebase you'll find quite a few other examples of the kinds of ways it usually gets used.

like image 168
Phil Webb Avatar answered Oct 18 '22 19:10

Phil Webb