Starter for testing Spring Boot applications with libraries including JUnit Jupiter, Hamcrest and Mockito
—
Application context testing utilities for testing auto-configuration, context behavior, and Spring Boot's application context management with context runners and AssertJ integration.
Utility for testing ApplicationContext configurations and auto-configuration behavior.
/**
* ApplicationContext runner for testing auto-configuration and context behavior
* @since 2.0.0
*/
public class ApplicationContextRunner extends AbstractApplicationContextRunner<ApplicationContextRunner, ConfigurableApplicationContext, AssertableApplicationContext> {
/**
* Create a new ApplicationContextRunner
*/
public ApplicationContextRunner();
/**
* Add configuration classes to the context
*/
public ApplicationContextRunner withConfiguration(Configurations configurations);
/**
* Add user configuration classes to the context
*/
public ApplicationContextRunner withUserConfiguration(Class<?>... configurationClasses);
/**
* Add property values to the context environment
*/
public ApplicationContextRunner withPropertyValues(String... pairs);
/**
* Add system properties to the context environment
*/
public ApplicationContextRunner withSystemProperties(String... pairs);
/**
* Set the class loader for the context
*/
public ApplicationContextRunner withClassLoader(ClassLoader classLoader);
/**
* Add parent context for the context
*/
public ApplicationContextRunner withParent(ApplicationContext parent);
/**
* Run the context and execute the given consumer
*/
public ApplicationContextRunner run(ContextConsumer<? super AssertableApplicationContext> consumer);
/**
* Prepare a context but don't run it yet
*/
public PreparedApplicationContext prepare();
}
/**
* Base class for application context runners
*/
public abstract class AbstractApplicationContextRunner<SELF extends AbstractApplicationContextRunner<SELF, C, A>, C extends ConfigurableApplicationContext, A extends AssertableApplicationContext> {
/**
* Create a copy of this runner with additional configuration
*/
protected abstract SELF newInstance(RunnerConfiguration<C> runnerConfiguration);
}Usage Examples:
class ApplicationContextRunnerTest {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner();
@Test
void autoConfigurationIsApplied() {
contextRunner
.withConfiguration(AutoConfigurations.of(MyAutoConfiguration.class))
.run(context -> {
assertThat(context).hasSingleBean(MyService.class);
assertThat(context).hasSingleBean(MyRepository.class);
});
}
@Test
void propertyConfiguresBean() {
contextRunner
.withConfiguration(AutoConfigurations.of(MyAutoConfiguration.class))
.withPropertyValues("myservice.enabled=false")
.run(context -> {
assertThat(context).doesNotHaveBean(MyService.class);
});
}
@Test
void userConfigurationOverridesAutoConfiguration() {
contextRunner
.withConfiguration(AutoConfigurations.of(MyAutoConfiguration.class))
.withUserConfiguration(CustomMyServiceConfiguration.class)
.run(context -> {
assertThat(context).hasSingleBean(MyService.class);
assertThat(context.getBean(MyService.class))
.isInstanceOf(CustomMyService.class);
});
}
@Test
void contextFailsWithInvalidConfiguration() {
contextRunner
.withConfiguration(AutoConfigurations.of(BrokenAutoConfiguration.class))
.run(context -> {
assertThat(context).hasFailed();
assertThat(context.getStartupFailure())
.hasMessageContaining("Configuration error");
});
}
}Context runner specifically for testing web application contexts.
/**
* WebApplicationContext runner for testing web-specific configurations
* @since 2.0.0
*/
public class WebApplicationContextRunner extends AbstractApplicationContextRunner<WebApplicationContextRunner, ConfigurableWebApplicationContext, AssertableWebApplicationContext> {
/**
* Create a new WebApplicationContextRunner
*/
public WebApplicationContextRunner();
/**
* Create a new WebApplicationContextRunner with specific context class
*/
public WebApplicationContextRunner(Class<? extends ConfigurableWebApplicationContext> contextClass);
/**
* Run the web context and execute the given consumer
*/
public WebApplicationContextRunner run(ContextConsumer<? super AssertableWebApplicationContext> consumer);
}Usage Examples:
class WebApplicationContextRunnerTest {
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner();
@Test
void webAutoConfigurationIsApplied() {
contextRunner
.withConfiguration(AutoConfigurations.of(
WebMvcAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class
))
.run(context -> {
assertThat(context).hasSingleBean(DispatcherServlet.class);
assertThat(context).hasBean("dispatcherServletRegistration");
});
}
@Test
void customWebConfiguration() {
contextRunner
.withUserConfiguration(CustomWebConfiguration.class)
.run(context -> {
assertThat(context).hasSingleBean(WebMvcConfigurer.class);
});
}
}Context runner for testing reactive web application contexts.
/**
* ReactiveWebApplicationContext runner for testing reactive web configurations
* @since 2.0.0
*/
public class ReactiveWebApplicationContextRunner extends AbstractApplicationContextRunner<ReactiveWebApplicationContextRunner, ConfigurableReactiveWebApplicationContext, AssertableReactiveWebApplicationContext> {
/**
* Create a new ReactiveWebApplicationContextRunner
*/
public ReactiveWebApplicationContextRunner();
/**
* Create a new ReactiveWebApplicationContextRunner with specific context class
*/
public ReactiveWebApplicationContextRunner(Class<? extends ConfigurableReactiveWebApplicationContext> contextClass);
/**
* Run the reactive web context and execute the given consumer
*/
public ReactiveWebApplicationContextRunner run(ContextConsumer<? super AssertableReactiveWebApplicationContext> consumer);
}Functional interface for consuming and testing application contexts.
/**
* Functional interface for consuming ApplicationContext in tests
* @since 2.0.0
*/
@FunctionalInterface
public interface ContextConsumer<C extends ApplicationContext> {
/**
* Accept and test the given context
*/
void accept(C context) throws Throwable;
}AssertJ-integrated application context for fluent testing.
/**
* An ApplicationContext that can be used with AssertJ assertions
* @since 2.0.0
*/
public interface AssertableApplicationContext extends ApplicationContext, ApplicationContextAssertProvider<AssertableApplicationContext> {
/**
* Get the startup failure if the context failed to start
*/
Throwable getStartupFailure();
/**
* Close the context and return itself for chaining
*/
AssertableApplicationContext closeAndReturn();
}
/**
* An AssertableApplicationContext for web applications
*/
public interface AssertableWebApplicationContext extends AssertableApplicationContext, WebApplicationContext, ApplicationContextAssertProvider<AssertableWebApplicationContext> {
}
/**
* An AssertableApplicationContext for reactive web applications
*/
public interface AssertableReactiveWebApplicationContext extends AssertableApplicationContext, ReactiveWebApplicationContext, ApplicationContextAssertProvider<AssertableReactiveWebApplicationContext> {
}AssertJ assertions specifically designed for Spring application contexts.
/**
* AssertJ assertions for ApplicationContext
* @since 2.0.0
*/
public class ApplicationContextAssert<C extends ApplicationContext> extends AbstractAssert<ApplicationContextAssert<C>, C> {
/**
* Verify that the context has a bean with the given name
*/
public ApplicationContextAssert<C> hasBean(String name);
/**
* Verify that the context does not have a bean with the given name
*/
public ApplicationContextAssert<C> doesNotHaveBean(String name);
/**
* Verify that the context has a single bean of the given type
*/
public ApplicationContextAssert<C> hasSingleBean(Class<?> type);
/**
* Verify that the context does not have a bean of the given type
*/
public ApplicationContextAssert<C> doesNotHaveBean(Class<?> type);
/**
* Verify that the context has failed to start
*/
public ApplicationContextAssert<C> hasFailed();
/**
* Verify that the context has not failed to start
*/
public ApplicationContextAssert<C> hasNotFailed();
/**
* Get bean assertions for the bean with the given name
*/
public ObjectAssert<Object> getBean(String name);
/**
* Get bean assertions for the bean of the given type
*/
public <T> ObjectAssert<T> getBean(Class<T> type);
/**
* Get bean assertions for the bean with the given name and type
*/
public <T> ObjectAssert<T> getBean(String name, Class<T> type);
/**
* Get failure assertions if the context failed to start
*/
public ThrowableAssert getStartupFailure();
}
/**
* Provider interface for ApplicationContext assertions
*/
public interface ApplicationContextAssertProvider<C extends ApplicationContext> {
/**
* Create AssertJ assertions for this context
*/
ApplicationContextAssert<C> assertThat();
}Utility for managing auto-configuration classes in tests.
/**
* Utility for creating Configurations for use with context runners
* @since 2.0.0
*/
public final class Configurations {
/**
* Create auto-configurations
*/
public static AutoConfigurations of(Class<?>... configurations);
/**
* Create user configurations
*/
public static UserConfigurations of(Class<?>... configurations);
/**
* Combine multiple configurations
*/
public static Configurations of(Configurations... configurations);
}
/**
* Auto-configurations for use with context runners
*/
public final class AutoConfigurations extends Configurations {
/**
* Create auto-configurations from the given classes
*/
public static AutoConfigurations of(Class<?>... configurations);
}
/**
* User configurations for use with context runners
*/
public final class UserConfigurations extends Configurations {
/**
* Create user configurations from the given classes
*/
public static UserConfigurations of(Class<?>... configurations);
}Advanced patterns for comprehensive context testing scenarios.
Usage Examples:
class AdvancedContextTestingTest {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner();
@Test
void contextWithMultipleAutoConfigurations() {
contextRunner
.withConfiguration(AutoConfigurations.of(
DataSourceAutoConfiguration.class,
JpaRepositoriesAutoConfiguration.class,
HibernateJpaAutoConfiguration.class
))
.withPropertyValues(
"spring.datasource.url=jdbc:h2:mem:testdb",
"spring.jpa.hibernate.ddl-auto=create-drop"
)
.run(context -> {
assertThat(context).hasSingleBean(DataSource.class);
assertThat(context).hasSingleBean(EntityManagerFactory.class);
assertThat(context).hasBean("transactionManager");
DataSource dataSource = context.getBean(DataSource.class);
assertThat(dataSource).isNotNull();
});
}
@Test
void conditionalBeanConfiguration() {
contextRunner
.withConfiguration(AutoConfigurations.of(ConditionalAutoConfiguration.class))
.withPropertyValues("feature.enabled=true")
.run(context -> {
assertThat(context).hasSingleBean(FeatureService.class);
});
contextRunner
.withConfiguration(AutoConfigurations.of(ConditionalAutoConfiguration.class))
.withPropertyValues("feature.enabled=false")
.run(context -> {
assertThat(context).doesNotHaveBean(FeatureService.class);
});
}
@Test
void contextWithParent() {
ApplicationContextRunner parentRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(ParentConfiguration.class));
parentRunner.run(parent -> {
contextRunner
.withParent(parent)
.withConfiguration(AutoConfigurations.of(ChildConfiguration.class))
.run(child -> {
assertThat(child).hasSingleBean(ChildService.class);
assertThat(child).hasSingleBean(ParentService.class);
// Verify bean from parent is available in child
ParentService parentService = child.getBean(ParentService.class);
assertThat(parentService).isNotNull();
});
});
}
@Test
void contextWithCustomClassLoader() {
URLClassLoader customClassLoader = new URLClassLoader(new URL[0], getClass().getClassLoader());
contextRunner
.withClassLoader(customClassLoader)
.withConfiguration(AutoConfigurations.of(MyAutoConfiguration.class))
.run(context -> {
assertThat(context.getClassLoader()).isEqualTo(customClassLoader);
assertThat(context).hasSingleBean(MyService.class);
});
}
@Test
void contextFailureAnalysis() {
contextRunner
.withConfiguration(AutoConfigurations.of(FailingAutoConfiguration.class))
.run(context -> {
assertThat(context).hasFailed();
assertThat(context.getStartupFailure())
.isInstanceOf(BeanCreationException.class)
.hasMessageContaining("Required dependency not found");
});
}
@Test
void contextWithTestPropertySource() {
contextRunner
.withConfiguration(AutoConfigurations.of(PropertyBasedConfiguration.class))
.withPropertyValues(
"app.name=Test Application",
"app.version=1.0.0",
"app.debug=true",
"logging.level.com.example=DEBUG"
)
.run(context -> {
ApplicationProperties props = context.getBean(ApplicationProperties.class);
assertThat(props.getName()).isEqualTo("Test Application");
assertThat(props.getVersion()).isEqualTo("1.0.0");
assertThat(props.isDebug()).isTrue();
});
}
@Test
void contextWithSystemProperties() {
contextRunner
.withSystemProperties(
"java.awt.headless=true",
"spring.profiles.active=test"
)
.withConfiguration(AutoConfigurations.of(ProfileBasedConfiguration.class))
.run(context -> {
assertThat(context).hasSingleBean(TestProfileService.class);
assertThat(System.getProperty("java.awt.headless")).isEqualTo("true");
});
}
@Test
void preparedContextUsage() {
PreparedApplicationContext prepared = contextRunner
.withConfiguration(AutoConfigurations.of(MyAutoConfiguration.class))
.withPropertyValues("service.name=prepared-service")
.prepare();
// Context is prepared but not started yet
assertThat(prepared).isNotNull();
// Now run the prepared context
prepared.run(context -> {
assertThat(context).hasSingleBean(MyService.class);
MyService service = context.getBean(MyService.class);
assertThat(service.getName()).isEqualTo("prepared-service");
});
}
}
// Example auto-configuration for testing
@Configuration
@ConditionalOnProperty(name = "feature.enabled", havingValue = "true")
static class ConditionalAutoConfiguration {
@Bean
public FeatureService featureService() {
return new FeatureService();
}
}
// Example configuration properties
@ConfigurationProperties(prefix = "app")
static class ApplicationProperties {
private String name;
private String version;
private boolean debug;
// getters and setters
}Install with Tessl CLI
npx tessl i tessl/maven-org-springframework-boot--spring-boot-starter-test