[ad_1]
Asked
Viewed
116k times
What am I doing wrong? I’m using this little standalone App which runs and finds my src/main/resources/config/application.yml
. The same configuration doesn’t work from JUnit, see below:
@Configuration
@ComponentScan
@EnableConfigurationProperties
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class);
}
}
@Component
@ConfigurationProperties
public class Bean{
...
}
The following doesn’t work, the same properties in application.yml
are not loaded and Bean
has only null
values:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = TestApplication.class)
public class SomeTestClass {
...
}
Try this:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = TestApplication.class,
initializers = ConfigFileApplicationContextInitializer.class)
public class SomeTestClass {
...
}
EDIT:
For Spring Boot version 1.5+, SpringApplicationConfiguration
was removed in favour of SpringBootTest
or direct use of SpringBootContextLoader
.
You can still use initializers
parameter with ContextConfiguration
annotation.
2
The trick to load any custom yml file in SpringBoot 2.0 w/o using @SpringBootTest
- create some yml file in test\resources
- Use
ConfigFileApplicationContextInitializer
andspring.config.location
property
Example Code:
@RunWith(SpringRunner.class)
@ContextConfiguration(
classes = { MyConfiguration.class, AnotherDependancy.class },
initializers = {ConfigFileApplicationContextInitializer.class} )
@TestPropertySource(properties = { "spring.config.location=classpath:myApp-test.yml" })
public class ConfigProviderTest {
@Autowired
private MyConfiguration myConfiguration; //this will be filled with myApp-test.yml
@Value("${my.config-yml-string}")
private String someSrting; //will get value from the yml file.
}
For JUnit 5 use the @ExtendWith(SpringExtension.class)
annotation instead of @RunWith(SpringRunner.class)
4
Alternative in February 2017:
@SpringBootTest
@ContextConfiguration(classes = { TestApplication.class })
@RunWith(SpringRunner.class)
public class SomeTestClass {
...
}
the lean variant (withouth @SpringBootTest
):
@ContextConfiguration(classes = { TestApplication.class },
initializers = { ConfigFileApplicationContextInitializer.class })
@RunWith(SpringRunner.class)
public class SomeTestClass {
3
Here’s another way: [Spring Boot v1.4.x]
@Configuration
@ConfigurationProperties(prefix = "own")
public class OwnSettings {
private String name;
Getter & setters...
}
import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@BootstrapWith(SpringBootTestContextBootstrapper.class)
public class OwnSettingsTest {
@Autowired
private OwnSettings bean;
@Test
public void test() {
bean.getName();
}
}
This works ONLY if also ‘application.properties’ file exists.
e.g. maven project:
src/main/resources/application.properties [ The file can be empty but it’s mandatory! ]
src/main/resources/application.yml [here’s your real config file]
4
Unit test with Spring Boot 2
spring boot 2 support ‘application.properties’ by default,
for ‘application.yml’ just add below:
@TestPropertySource(properties = { "spring.config.location=classpath:application.yml" })
e.g.
@RunWith(SpringRunner.class)
@SpringBootTest
@TestPropertySource(properties = { "spring.config.location=classpath:application.yml" })
public class ServiceTest {...}
adding to Liam’s answer, an alternative will be:
@TestPropertySource(locations = { "classpath:application.yaml" })
the key difference here is that the test will fail with a file not found exception if application.yaml
is not in your /test/resources
directory
Since spring-boot version 2.6.0 org.springframework.boot.test.context.ConfigFileApplicationContextInitializer
is deprecated and instead is recommended to be used org.springframework.boot.test.context.ConfigDataApplicationContextInitializer
.
In your tests you can use it as:
@ContextConfiguration(classes = {
...
}, initializers = ConfigDataApplicationContextInitializer.class)
public class MyTestingClassIT
1
Spring boot 2 example:
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withInitializer(new ConfigFileApplicationContextInitializer());
@Test public void test() throws Exception {
this.contextRunner
.withUserConfiguration(TestApplication.class)
.run((context) -> {
.....
});
}
1
In my case I was trying to test a library without a @SpringBootApp
declared in the regular app classpath, but I do have one in my test context. After debugging my way through the Spring Boot initialization process, I discovered that Spring Boot’s YamlPropertySourceLoader (as of 1.5.2.RELEASE) will not load YAML properties unless org.yaml.snakeyaml.Yaml
is on the classpath. The solution for me was to add snakeyaml as a test dependency in my POM:
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.19</version>
<scope>test</scope>
</dependency>
extending Liam’s answer
you can add spring.config.additional-location=classpath:application-overrides.yaml
property so config from default location will be merged with the additional config provided:
@RunWith(SpringRunner.class)
@SpringBootTest
@TestPropertySource(properties = {
"spring.config.additional-location=classpath:testcases/test-case-properties.yaml",
})
public class SpecificTestCaseIntegrationTest {
This works
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTest {
@Test
public void contextLoads() {
}
}
1
lang-java
[ad_2]