Load different application.yml in SpringBoot Test

2020-02-07 16:21发布

I'm using a spring boot app which runs my src/main/resources/config/application.yml.

When I run my test case by :

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
@IntegrationTest
public class MyIntTest{
}

The test codes still run my application.yml file to load properties. I wonder if it is possible to run another *.yml file when running the test case.

10条回答
别忘想泡老子
2楼-- · 2020-02-07 17:01

We can use @SpringBootTest annotation which loads the yml file from src\main\java\com...hence when we execute the unit test, all of the properties are already there in the config properties class.

@RunWith(SpringRunner.class)
@SpringBootTest
public class AddressFieldsTest {

    @InjectMocks
    AddressFieldsValidator addressFieldsValidator;

    @Autowired
    AddressFieldsConfig addressFieldsConfig;
    ...........

    @Before
    public void setUp() throws Exception{
        MockitoAnnotations.initMocks(this);
        ReflectionTestUtils.setField(addressFieldsValidator,"addressFieldsConfig", addressFieldsConfig);
    }

}

We can use @Value annotation if you have few configs or other wise we can use a config properties class. For e.g

@Data
@Component
@RefreshScope
@ConfigurationProperties(prefix = "address.fields.regex")
public class AddressFieldsConfig {

    private int firstName;
    private int lastName;
    .........
查看更多
Explosion°爆炸
3楼-- · 2020-02-07 17:07

If you need to have production application.yml completely replaced then put its test version to the same path but in test environment (usually it is src/test/resources/)

But if you need to override or add some properties then you have few options.

Option 1: put test application.yml in src/test/resources/config/ directory as @TheKojuEffect suggests in his answer.

Option 2: use profile-specific properties: create say application-test.yml in your src/test/resources/ folder and:

  • add @ActiveProfiles annotation to your test classes:

    @SpringBootTest(classes = Application.class)
    @ActiveProfiles("test")
    public class MyIntTest {
    
  • or alternatively set spring.profiles.active property value in @SpringBootTest annotation:

    @SpringBootTest(
            properties = ["spring.profiles.active=test"],
            classes = Application.class,
    )
    public class MyIntTest {
    

This works not only with @SpringBootTest but with @JsonTest, @JdbcTests, @DataJpaTest and other slice test annotations as well.

And you can set as many profiles as you want (spring.profiles.active=dev,hsqldb) - see farther details in documentation on Profiles.

查看更多
倾城 Initia
4楼-- · 2020-02-07 17:09

Starting with Spring 4.1, We can directly set the property in application.yml using the @TestPropertySource annotation.

@RunWith(SpringRunner.class)
@SpringBootTest
@TestPropertySource(properties = {"yoursection.yourparameter=your_value"})
public MyIntTest
{
 //your test methods
}

Just convert your yaml parameters into complete property structure. For example: If content of application.yml is like below

yoursection:
  yourparameter:your_value

Then value to go inside the @TestPropertySource will be,

yoursection.yourparameter=your_value
查看更多
啃猪蹄的小仙女
5楼-- · 2020-02-07 17:10

You can set your test properties in src/test/resources/config/application.yml file. Spring Boot test cases will take properties from application.yml file in test directory.

查看更多
闹够了就滚
6楼-- · 2020-02-07 17:10

Spring-boot framework allows us to provide YAML files as a replacement for the .properties file and it is convenient.The keys in property files can be provided in YAML format in application.yml file in the resource folder and spring-boot will automatically take it up.Keep in mind that the yaml format has to keep the spaces correct for the value to be read correctly.

You can use the @Value("${property}") to inject the values from the YAML files. Also Spring.active.profiles can be given, to differentiate between different YAML for different environments for convenient deployment.

For testing purposes, the test yaml file can be name like application-test.yml and placed in the resource folder of the test directory.

If you are specifying the applciation-test.yml and provide the spring test profile in the yml, then you can use the @ActiveProfiles('test') annotation to direct spring to take the configurations from the application-test.yml that you have specified.

@RunWith(SpringRunner.class)
@SpringBootTest(classes = ApplicationTest.class)
@ActiveProfiles("test")
public class MyTest {
 ...
}

If you are using JUnit 5 then no need for other annotations as @SpringBootTest already include the springrunner annotation. Keeping a separate main ApplicationTest.class enables us to provide separate configuration classes for tests and we can prevent the default configuration beans from loading by excluding them from component scan in the test main class. You can also provide the profile to be loaded there.

@SpringBootApplication(exclude=SecurityAutoConfiguration.class)
public class ApplicationTest {

    public static void main(String[] args) {
        SpringApplication.run(ApplicationTest.class, args);
    }
}

Here is the link for Spring documentation regarding use of YAML instead of .properties file(s): https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

查看更多
乱世女痞
7楼-- · 2020-02-07 17:12

One option is to work with profiles. Create a file called application-test.yml, move all properties you need for those tests to that file and then add the @ActiveProfiles annotation to your test class:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
@IntegrationTest
@ActiveProfiles("test") // Like this
public class MyIntTest{
}

Be aware, it will additionally load the application-test.yml, so all properties that are in application.yml are still going to be applied as well. If you don't want that, either use a profile for those as well, or override them in your application-test.yml.

查看更多
登录 后发表回答