1. Introduction
In this quick article, we’ll take a look at the new @SpringJUnitConfig and @SpringJUnitWebConfig annotations available in Spring and Spring Boot.
These annotations are a composition of JUnit 5 and Spring annotations that make test creation easier and faster.
2. @SpringJUnitConfig
@SpringJUnitConfig combines these 2 annotations:
- @ExtendWith(SpringExtension.class) from JUnit 5 to run the test with the SpringExtension class and
- @ContextConfiguration from Spring Testing to load the Spring context
2.1. Test Configuration
Let’s create a test and use this annotation in practice:
@SpringJUnitConfig(SpringJUnitConfigIntegrationTest.Config.class)
public class SpringJUnitConfigIntegrationTest {
@Configuration
static class Config {}
}
Notice that, in contrast to the @ContextConfiguration, configuration classes are declared using the value attribute. However, resource locations should be specified with the locations attribute.
We can now verify that the Spring context was really loaded:
@Autowired
private ApplicationContext applicationContext;
@Test
void givenAppContext_WhenInjected_ThenItShouldNotBeNull() {
assertNotNull(applicationContext);
}
Finally, here we have the equivalent code of @SpringJUnitConfig(SpringJUnitConfigTest.Config.class):
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = SpringJUnitConfigTest.Config.class)
2.2. The loader Attribute
One of the attributes of @ContextConfiguration named loader wasn’t an attribute in @SpringJUnitConfig when it was initially released. In a case where we need to explicitly set a custom loader, we have to revert to the lower-level annotations:
@ExtendWith(SpringExtension.class)
@ContextConfiguration(loader = SpringConfigTest.class)
As of Spring version 6 and Spring Boot version 3.2.0, the loader attribute is available as a parameter in the @SpringJUnitConfig annotation. This provides support for configuring a custom ContextLoader or SmartContextLoader.
For example, let’s explicitly specify annotation-based loading directly in the @SpringJUnitConfig annotation:
@SpringJUnitConfig(classes = TestConfig.class, loader = AnnotationConfigContextLoader.class)
public class SpringJUnitConfigurationUnitTest {
@ParameterizedTest
@ValueSource(strings = { "Dilbert", "Wally" })
void whenSetPeopleWithName_thenListContainsOnePerson(String name, @Autowired List people) {
assertThat(people.stream()
.map(Person::getName)
.filter(name::equals)).hasSize(1);
}
}
Using the loader attribute, we have a simpler test configuration without the need for multiple annotations.
3. @SpringJUnitWebConfig
@SpringJUnitWebConfig combines the same annotations of @SpringJUnitConfig plus the @WebAppConfiguration from Spring testing – to load the WebApplicationContext.
Let’s see how this annotation works:
@SpringJUnitWebConfig(SpringJUnitWebConfigIntegrationTest.Config.class)
public class SpringJUnitWebConfigIntegrationTest {
@Configuration
static class Config {
}
}
Like @SpringJUnitConfig, the configuration classes go in the value attribute, and any resources are specified using the locations attribute.
Also, the value attribute of @WebAppConfiguration should now be specified using the resourcePath attribute. By default, this attribute is set to “src/main/webapp”.
Let’s now verify that the WebApplicationContext was really loaded:
@Autowired
private WebApplicationContext webAppContext;
@Test
void givenWebAppContext_WhenInjected_ThenItShouldNotBeNull() {
assertNotNull(webAppContext);
}
Again, here we have the equivalent code without using @SpringJUnitWebConfig:
@ExtendWith(SpringExtension.class)
@WebAppConfiguration
@ContextConfiguration(classes = SpringJUnitWebConfigIntegrationTest.Config.class)
Similarly, Spring version 6 and Spring Boot version 3.2.0 add loader support to @SpringJUnitWebConfig to configure a custom context loader for tests. This gives the annotation the full capabilities of @ContextConfiguration annotation.
4. Conclusion
In this brief tutorial, we showed how to use the introduced @SpringJUnitConfig and @SpringJUnitWebConfig annotations in Spring 5 and above.
As always, the full source code for the examples is available over on GitHub.