or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

assertj-integration.mdcontext-runners.mdindex.mdintegration-testing.mdjson-testing.mdoutput-capture.mdtest-configuration.mdtest-properties.mdweb-test-utilities.md
tile.json

integration-testing.mddocs/

Integration Testing with @SpringBootTest

Complete Spring Boot application context testing with automatic configuration detection, multiple web environment modes, and property/argument injection.

Package

org.springframework.boot.test.context

Prerequisites

  • JUnit 5 (Jupiter)
  • @SpringBootApplication or @SpringBootConfiguration in classpath
  • Test must be in same package or subpackage as main application class

Core Imports

import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.boot.test.web.server.LocalManagementPort;
import org.springframework.beans.factory.annotation.Autowired;
import org.junit.jupiter.api.Test;

@SpringBootTest Annotation

Full Package: org.springframework.boot.test.context.SpringBootTest Since: 1.4.0

Main annotation for Spring Boot integration tests that loads full application context with Spring Boot features including auto-configuration, custom Environment properties, application arguments, and multiple web environment modes.

/**
 * Annotation for Spring Boot integration tests
 * Triggers SpringBootTestContextBootstrapper for custom test context setup
 * Automatically searches for @SpringBootConfiguration if classes not specified
 * @since 1.4.0
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@BootstrapWith(SpringBootTestContextBootstrapper.class)
@ExtendWith(SpringExtension.class)
public @interface SpringBootTest {

    /**
     * Alias for properties() - use for simple property definitions
     * Convenient shorthand when only defining properties
     * @return properties in key=value format
     */
    String[] value() default {};

    /**
     * Properties in key=value format added to Environment before test runs
     * Properties have higher precedence than application.properties
     * Format: "key=value" or "key:value"
     * Example: {"server.port=0", "spring.datasource.url=jdbc:h2:mem:testdb"}
     * @return property definitions
     */
    String[] properties() default {};

    /**
     * Application arguments passed to main method
     * Only used when useMainMethod != NEVER
     * Format: standard command-line args like "--debug" or "--spring.profiles.active=test"
     * @return application arguments
     * @since 2.2.0
     */
    String[] args() default {};

    /**
     * Configuration classes for the application context
     * If empty, searches for @SpringBootConfiguration in package hierarchy
     * Useful for limiting context to specific configurations
     * @return configuration classes
     */
    Class<?>[] classes() default {};

    /**
     * Web environment mode for the test
     * Determines if/how an embedded web server is started
     * @return the web environment mode (defaults to MOCK)
     */
    WebEnvironment webEnvironment() default WebEnvironment.MOCK;

    /**
     * Whether to use the application main method for context initialization
     * ALWAYS: Always invoke main method
     * NEVER: Never invoke main method (standard Spring Boot test behavior)
     * WHEN_AVAILABLE: Invoke if main method exists
     * @return main method usage mode (defaults to NEVER)
     * @since 3.0.0
     */
    UseMainMethod useMainMethod() default UseMainMethod.NEVER;

    /**
     * Web environment modes for integration tests
     * Determines how the application context is configured for web testing
     */
    enum WebEnvironment {
        /**
         * Mock web environment - loads WebApplicationContext with MockMvc support
         * No embedded server is started
         * Use with @AutoConfigureMockMvc for MockMvc testing
         * Suitable for controller layer testing without network stack
         */
        MOCK,

        /**
         * Start embedded web server on a random available port
         * Ideal for integration tests to avoid port conflicts
         * Port can be injected with @LocalServerPort
         * Creates full network stack for realistic testing
         */
        RANDOM_PORT,

        /**
         * Start embedded server on the port defined in properties
         * Uses server.port from configuration (default 8080)
         * Can cause port conflicts if not managed carefully
         * Useful when tests need predictable port numbers
         */
        DEFINED_PORT,

        /**
         * No web environment - loads standard ApplicationContext
         * Use for testing non-web components or services
         * Lighter weight than MOCK as no web infrastructure is loaded
         * Best for business logic and data layer testing
         */
        NONE;

        /**
         * Check if this environment uses an embedded web server
         * @return true for RANDOM_PORT and DEFINED_PORT, false for MOCK and NONE
         */
        public boolean isEmbedded();
    }

    /**
     * Main method usage modes
     * Controls whether the application main method is invoked during test setup
     */
    enum UseMainMethod {
        /**
         * Always use the main method for context initialization
         * Test fails if main method not found
         * Ensures test environment matches production startup
         */
        ALWAYS,

        /**
         * Never use the main method (default behavior)
         * Standard Spring Boot test context initialization
         * Faster and more predictable for most tests
         */
        NEVER,

        /**
         * Use main method when available, fall back to standard if not
         * Flexible option for shared test infrastructure
         * Useful in multi-module projects with varying main method presence
         */
        WHEN_AVAILABLE
    }
}

Common Usage Patterns

Pattern: Basic Integration Test

import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest
class BasicIntegrationTest {

    @Autowired
    private MyService service;

    @Test
    void testServiceMethod() {
        assertThat(service.process("input")).isNotNull();
    }
}

Pattern: Random Port with REST Testing

import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpStatus;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class RandomPortTest {

    @LocalServerPort
    private int port; // Injected after server starts

    @Autowired
    private TestRestTemplate restTemplate; // Auto-configured

    @Test
    void testEndpoint() {
        ResponseEntity<String> response = restTemplate.getForEntity(
            "/api/test", String.class);
        assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
    }
}

Pattern: Custom Properties

@SpringBootTest(properties = {
    "spring.datasource.url=jdbc:h2:mem:testdb",
    "custom.feature.enabled=true",
    "server.port=0" // 0 for random port
})
class PropertiesTest {
    // Properties are added to Environment before context starts
}

Pattern: Specific Configuration Classes

@SpringBootTest(classes = {TestConfig.class, ServiceConfig.class})
class CustomConfigTest {
    // Only specified configurations are loaded
    // Auto-configuration still applies unless excluded
}

Port Injection Annotations

@LocalServerPort

Full Package: org.springframework.boot.test.web.server.LocalServerPort Since: 2.7.0

Injects the HTTP server port that was allocated at runtime. Provides a convenient alternative for @Value("${local.server.port}").

/**
 * Annotation at the field or method/constructor parameter level that injects the HTTP
 * server port that was allocated at runtime. Provides a convenient alternative for
 * @Value("${local.server.port}") with the assumption that the
 * web server implementation has configured such a property.
 * @since 2.7.0
 */
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Value("${local.server.port}")
public @interface LocalServerPort {
}

Usage:

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class PortInjectionTest {
    @LocalServerPort
    private int port; // Injects actual server port
}

Constraints:

  • Only works with RANDOM_PORT or DEFINED_PORT
  • Field must be int or Integer type
  • Injected after server startup

@LocalManagementPort

Full Package: org.springframework.boot.test.web.server.LocalManagementPort Since: 2.7.0

Injects the HTTP management port that was allocated at runtime when management server is configured separately. Provides a convenient alternative for @Value("${local.management.port}").

/**
 * Annotation at the field or method/constructor parameter level that injects the HTTP
 * management port that was allocated at runtime. Provides a convenient alternative for
 * @Value("${local.management.port}") with the assumption that the management web
 * server implementation has configured such a property.
 * @since 2.7.0
 */
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Value("${local.management.port}")
public @interface LocalManagementPort {
}

Usage:

@SpringBootTest(
    webEnvironment = WebEnvironment.RANDOM_PORT,
    properties = "management.server.port=0"
)
class ManagementPortTest {
    @LocalManagementPort
    private int managementPort;
}

Advanced Annotations

@PropertyMapping

Full Package: org.springframework.boot.test.context.PropertyMapping Since: 4.0.0

Maps test annotation attributes to environment properties for declarative configuration.

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PropertyMapping {
    String value() default "";  // Property name or prefix
    Skip skip() default Skip.NO;

    enum Skip {
        YES,                    // Skip mapping this property
        ON_DEFAULT_VALUE,       // Skip if default value
        NO                      // Always map (default)
    }
}

Usage Pattern:

// Define custom test annotation with property mapping
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@PropertyMapping("app.test")
public @interface TestWithConfig {
    String environment() default "test";

    @PropertyMapping(skip = PropertyMapping.Skip.ON_DEFAULT_VALUE)
    String optionalValue() default "";
}

// Use annotation - maps to app.test.environment and app.test.optional-value
@SpringBootTest
@TestWithConfig(environment = "integration")
class MyTest {
    @Value("${app.test.environment}")
    private String env; // injected as "integration"
}

@TypeExcludeFilters

Full Package: org.springframework.boot.test.context.filter.annotation.TypeExcludeFilters Since: 4.0.0

Registers TypeExcludeFilter classes for component scanning control. Filters can be used to exclude specific types from being registered with the ApplicationContext during tests.

/**
 * Annotation that can be on tests to define a set of TypeExcludeFilter classes
 * that should be registered with the ApplicationContext.
 * Filter classes can either have a no-arg constructor or accept a single
 * Class<?> argument if they need access to the testClass.
 * @since 4.0.0
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface TypeExcludeFilters {
    /**
     * Specifies TypeExcludeFilter classes that should be registered
     * @return the type exclude filters to apply
     */
    Class<? extends TypeExcludeFilter>[] value();
}

Usage Pattern:

// Custom filter implementation
public class TestComponentFilter extends TypeExcludeFilter {
    @Override
    public boolean match(MetadataReader reader, MetadataReaderFactory factory) {
        return reader.getClassMetadata().getClassName().contains("Mock");
    }
}

// Apply filter to test
@SpringBootTest
@TypeExcludeFilters(TestComponentFilter.class)
class FilteredTest {
    // Mock components excluded from context
}

Complete API Reference

Framework Classes

SpringBootContextLoader

Full Package: org.springframework.boot.test.context.SpringBootContextLoader Since: 1.4.0

Context loader for @SpringBootTest. Uses SpringApplication for proper initialization.

public class SpringBootContextLoader extends AbstractContextLoader implements AotContextLoader {
    // Load context for test execution
    public ApplicationContext loadContext(MergedContextConfiguration config) throws Exception;

    // AOT processing support (since 3.0.0)
    public ApplicationContext loadContextForAotProcessing(
        MergedContextConfiguration config, RuntimeHints hints) throws Exception;

    public ApplicationContext loadContextForAotRuntime(
        MergedContextConfiguration config,
        ApplicationContextInitializer<ConfigurableApplicationContext> initializer) throws Exception;

    @Override
    public void processContextConfiguration(ContextConfigurationAttributes attrs);
}

SpringBootTestContextBootstrapper

Full Package: org.springframework.boot.test.context.SpringBootTestContextBootstrapper Since: 1.4.0

public class SpringBootTestContextBootstrapper extends DefaultTestContextBootstrapper {
    public SpringBootTestContextBootstrapper();

    @Override
    public TestContext buildTestContext();
}

ReactiveWebMergedContextConfiguration

Full Package: org.springframework.boot.test.context.ReactiveWebMergedContextConfiguration Since: 2.0.0

public class ReactiveWebMergedContextConfiguration extends MergedContextConfiguration {
    public ReactiveWebMergedContextConfiguration(MergedContextConfiguration mergedConfig);
}

SpringBootTestAotProcessor

Full Package: org.springframework.boot.test.context.SpringBootTestAotProcessor Since: 3.0.0

AOT processor for Spring Boot test classes. For framework use only.

public class SpringBootTestAotProcessor extends TestAotProcessor {
    public SpringBootTestAotProcessor(Set<Path> classpathRoots, Settings settings);

    // Entry point for command-line AOT processing
    public static void main(String[] args);
}

ConfigDataApplicationContextInitializer

Full Package: org.springframework.boot.test.context.ConfigDataApplicationContextInitializer Since: 2.4.0

Loads application.properties/yaml for tests. Can be used with @ContextConfiguration.

public class ConfigDataApplicationContextInitializer
        implements ApplicationContextInitializer<ConfigurableApplicationContext> {

    public ConfigDataApplicationContextInitializer();

    @Override
    public void initialize(ConfigurableApplicationContext context);
}

Usage:

@ContextConfiguration(
    classes = MyConfig.class,
    initializers = ConfigDataApplicationContextInitializer.class
)
class ConfigDataTest {
    // application.properties loaded automatically
}

Utility Classes

AnnotatedClassFinder

Full Package: org.springframework.boot.test.context.AnnotatedClassFinder Since: 2.1.0

Finds classes annotated with specific annotations in package hierarchy.

public final class AnnotatedClassFinder {
    public AnnotatedClassFinder(Class<? extends Annotation> annotationType);

    @Nullable
    public Class<?> findFromClass(Class<?> source);

    @Nullable
    public Class<?> findFromPackage(String source);
}

Usage:

// Find @SpringBootConfiguration from test class
AnnotatedClassFinder finder =
    new AnnotatedClassFinder(SpringBootConfiguration.class);
Class<?> config = finder.findFromClass(MyTest.class);

FilteredClassLoader

Full Package: org.springframework.boot.test.context.FilteredClassLoader Since: 2.0.0

Test ClassLoader that filters classes and resources to simulate classpath scenarios.

/**
 * Test URLClassLoader that can filter the classes and resources it can load
 * Used to test auto-configuration behavior when specific classes are absent
 * @since 2.0.0
 */
public class FilteredClassLoader extends URLClassLoader implements SmartClassLoader {

    /**
     * Create a FilteredClassLoader that hides the given classes
     * @param hiddenClasses the classes to hide
     */
    public FilteredClassLoader(Class<?>... hiddenClasses);

    /**
     * Create a FilteredClassLoader with the given parent that hides the given classes
     * @param parent the parent class loader
     * @param hiddenClasses the classes to hide
     */
    public FilteredClassLoader(ClassLoader parent, Class<?>... hiddenClasses);

    /**
     * Create a FilteredClassLoader that hides classes from the given packages
     * @param hiddenPackages the packages to hide
     */
    public FilteredClassLoader(String... hiddenPackages);

    /**
     * Create a FilteredClassLoader that hides resources from the given ClassPathResources
     * @param hiddenResources the resources to hide
     * @since 2.1.0
     */
    public FilteredClassLoader(ClassPathResource... hiddenResources);

    /**
     * Create a FilteredClassLoader that filters based on the given predicate
     * @param filters a set of filters to determine when a class name or resource should be hidden
     */
    public FilteredClassLoader(Predicate<String>... filters);

    /**
     * Filter to restrict the classes that can be loaded
     */
    public static final class ClassFilter implements Predicate<String> {
        public static ClassFilter of(Class<?>... hiddenClasses);
        public boolean test(String className);
    }

    /**
     * Filter to restrict the packages that can be loaded
     */
    public static final class PackageFilter implements Predicate<String> {
        public static PackageFilter of(String... hiddenPackages);
        public boolean test(String className);
    }

    /**
     * Filter to restrict the resources that can be loaded
     * @since 2.1.0
     */
    public static final class ClassPathResourceFilter implements Predicate<String> {
        public static ClassPathResourceFilter of(ClassPathResource... hiddenResources);
        public boolean test(String resourceName);
    }
}

Usage Examples:

import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;

// Test auto-configuration when Jackson is not available
new ApplicationContextRunner()
    .withClassLoader(new FilteredClassLoader(
        com.fasterxml.jackson.databind.ObjectMapper.class))
    .withUserConfiguration(JacksonAutoConfiguration.class)
    .run(context ->
        assertThat(context).doesNotHaveBean(ObjectMapper.class));

// Hide entire package
new ApplicationContextRunner()
    .withClassLoader(new FilteredClassLoader("com.example.optional"))
    .run(context -> {
        // Test behavior when optional package not present
    });

// Hide specific classpath resources
ClassPathResource resource = new ClassPathResource("META-INF/spring.factories");
new ApplicationContextRunner()
    .withClassLoader(new FilteredClassLoader(resource))
    .run(context -> {
        // Test behavior when resource is missing
    });

Advanced Type Filtering

AnnotationCustomizableTypeExcludeFilter

Full Package: org.springframework.boot.test.context.filter.annotation.AnnotationCustomizableTypeExcludeFilter Since: 4.0.0

Abstract base for annotation-based type filters. For custom test slice creation.

import org.springframework.context.annotation.ComponentScan.Filter;

public abstract class AnnotationCustomizableTypeExcludeFilter
        extends TypeExcludeFilter implements BeanClassLoaderAware {

    @Override
    public void setBeanClassLoader(ClassLoader classLoader);

    @Override
    public boolean match(MetadataReader reader, MetadataReaderFactory factory)
            throws IOException;

    protected abstract boolean hasAnnotation();
    protected abstract Filter[] getFilters(FilterType type);
    protected abstract boolean isUseDefaultFilters();
    protected abstract Set<Class<?>> getDefaultIncludes();
    protected abstract Set<Class<?>> getComponentIncludes();

    protected enum FilterType { INCLUDE, EXCLUDE }
}

StandardAnnotationCustomizableTypeExcludeFilter

Full Package: org.springframework.boot.test.context.filter.annotation.StandardAnnotationCustomizableTypeExcludeFilter<A> Since: 4.0.0

Generic implementation for standard filter annotations. Simplifies custom slice creation.

public abstract class StandardAnnotationCustomizableTypeExcludeFilter<A extends Annotation>
        extends AnnotationCustomizableTypeExcludeFilter {

    protected StandardAnnotationCustomizableTypeExcludeFilter(Class<?> testClass);

    protected final MergedAnnotation<A> getAnnotation();
    protected Class<A> getAnnotationType();
    protected Set<Class<?>> getKnownIncludes();
}

Usage Pattern:

import org.springframework.context.annotation.ComponentScan.Filter;

// Define custom slice annotation
@Retention(RetentionPolicy.RUNTIME)
@TypeExcludeFilters(MySliceFilter.class)
public @interface MySlice {
    Filter[] includeFilters() default {};
    Filter[] excludeFilters() default {};
    boolean useDefaultFilters() default true;
}

// Implement filter
public class MySliceFilter extends StandardAnnotationCustomizableTypeExcludeFilter<MySlice> {
    public MySliceFilter(Class<?> testClass) {
        super(testClass);
    }

    @Override
    protected Set<Class<?>> getKnownIncludes() {
        return Set.of(MyComponent.class, MyService.class);
    }

    @Override
    protected Set<Class<?>> getComponentIncludes() {
        return Set.of(org.springframework.stereotype.Component.class);
    }
}

// Use custom slice
@MySlice
class CustomSliceTest {
    // Only MyComponent and MyService types loaded
}

Additional Usage Patterns

Pattern: Testing with WebTestClient (Reactive)

import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.beans.factory.annotation.Autowired;

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class WebTestClientTest {

    @Autowired
    private WebTestClient webTestClient;

    @Test
    void testReactiveEndpoint() {
        webTestClient.get()
            .uri("/api/reactive")
            .exchange()
            .expectStatus().isOk()
            .expectBody(String.class)
            .value(body -> assertThat(body).isNotEmpty());
    }
}

Pattern: Combining with @TestConfiguration

import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;

@SpringBootTest
class TestWithCustomConfig {

    @TestConfiguration
    static class Config {
        @Bean
        public MyService testService() {
            return new MyTestService();
        }
    }

    @Autowired
    private MyService myService;

    @Test
    void testWithTestConfig() {
        assertThat(myService).isInstanceOf(MyTestService.class);
    }
}

Pattern: Testing with Application Arguments

import org.springframework.boot.ApplicationArguments;

@SpringBootTest(args = {"--debug", "--custom.arg=value"})
class ApplicationArgumentsTest {

    @Autowired
    private ApplicationArguments args;

    @Test
    void testArguments() {
        assertThat(args.containsOption("debug")).isTrue();
        assertThat(args.getOptionValues("custom.arg")).contains("value");
    }
}

Pattern: Non-Web Integration Test

@SpringBootTest(webEnvironment = WebEnvironment.NONE)
class NonWebIntegrationTest {

    @Autowired
    private DataService dataService;

    @Test
    void testDataService() {
        assertThat(dataService.getData()).isNotEmpty();
    }
}

Pattern: Testing with Multiple Configurations

@SpringBootTest(classes = {
    TestConfig.class,
    ServiceConfig.class,
    DataSourceConfig.class
})
class MultiConfigTest {

    @Autowired
    private ApplicationContext context;

    @Test
    void verifyAllConfigsLoaded() {
        assertThat(context).hasBean("testBean");
        assertThat(context).hasBean("serviceBean");
        assertThat(context).hasBean("dataSourceBean");
    }
}

Pattern: Testing with Profile-Specific Properties

import org.springframework.test.context.ActiveProfiles;

@SpringBootTest(properties = {
    "spring.profiles.active=test",
    "spring.datasource.url=jdbc:h2:mem:testdb"
})
@ActiveProfiles("test")
class ProfileTest {

    @Value("${spring.datasource.url}")
    private String datasourceUrl;

    @Test
    void testProfileProperties() {
        assertThat(datasourceUrl).contains("h2:mem");
    }
}

Pattern: Testing Async Operations

import org.springframework.scheduling.annotation.EnableAsync;
import java.util.concurrent.CompletableFuture;

@SpringBootTest
@EnableAsync
class AsyncTest {

    @Autowired
    private AsyncService asyncService;

    @Test
    void testAsyncMethod() throws Exception {
        CompletableFuture<String> result = asyncService.performAsync();

        assertThat(result.get()).isEqualTo("async result");
    }
}

Pattern: Testing with Parent Context

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

class ParentContextTest {

    @Test
    void testWithParentContext() {
        ApplicationContext parent = new AnnotationConfigApplicationContext(ParentConfig.class);

        // Child context can access parent beans
        // Note: Requires custom setup, not directly supported by @SpringBootTest
    }
}

Troubleshooting

Common Issues

Issue: NoSuchBeanDefinitionException in @SpringBootTest

  • Cause: Test class not in same package or subpackage as @SpringBootApplication
  • Solution: Move test to correct package or specify classes attribute explicitly
  • Example:
    @SpringBootTest(classes = {MyApplication.class, TestConfig.class})
    class MyTest { }

Issue: Port not injected (value is 0)

  • Cause: Wrong WebEnvironment mode
  • Solution: Use webEnvironment = WebEnvironment.RANDOM_PORT
  • Verification: Ensure @LocalServerPort field is int type

Issue: Properties not applied

  • Cause: Wrong syntax (missing = or using : instead)
  • Solution: Use "key=value" format, not "key:value"
  • Example: properties = {"server.port=8080"} not "server.port: 8080"

Issue: Context loads too slowly

  • Cause: Full context with all auto-configurations loaded
  • Solution: Use test slices (@WebMvcTest, @DataJpaTest) or context runners for faster tests
  • Alternative: Cache contexts by using consistent configuration across tests

Issue: TestRestTemplate returns null

  • Cause: Not using webEnvironment = RANDOM_PORT or DEFINED_PORT
  • Solution: TestRestTemplate only auto-configured with embedded server modes

Issue: Beans from @TestConfiguration not found

  • Cause: @TestConfiguration class is not inner static class or not in scan path
  • Solution: Make it a static inner class or place in test package

Issue: Context fails to start with circular dependency

  • Cause: Test configuration creates circular bean references
  • Solution: Use @Lazy, constructor injection, or withAllowCircularReferences in tests

Issue: Wrong database being used in tests

  • Cause: Production datasource properties override test properties
  • Solution: Set test properties with higher precedence or use test-specific configuration

Issue: Main method arguments not passed

  • Cause: useMainMethod is set to NEVER (default)
  • Solution: Set useMainMethod = UseMainMethod.ALWAYS or WHEN_AVAILABLE

Issue: Management port injection fails

  • Cause: Management server not configured on separate port
  • Solution: Add property "management.server.port=0"

Error Messages and Solutions

Error: "Unable to find @SpringBootConfiguration"

  • Cause: No @SpringBootConfiguration in package hierarchy
  • Solution: Add @SpringBootConfiguration or specify classes explicitly

Error: "Failed to load ApplicationContext"

  • Root Causes:
    • Missing dependencies in test scope
    • Invalid bean configuration
    • Database connection failures
  • Debug: Check stack trace for BeanCreationException details

Error: "Port already in use"

  • Cause: DEFINED_PORT used with hardcoded port that's occupied
  • Solution: Use RANDOM_PORT instead or ensure port is available

Error: "Bean definition names clash"

  • Cause: Multiple configurations define beans with same name
  • Solution: Use @Primary or enable bean definition overriding

Performance Tips

  1. Context Caching: Reuse the same configuration across tests to benefit from Spring's test context caching
  2. Use Test Slices: Prefer @WebMvcTest, @DataJpaTest over @SpringBootTest when possible
  3. Lazy Initialization: Enable spring.main.lazy-initialization=true in tests
  4. Disable Auto-configurations: Use @SpringBootTest(exclude = {...}) for unused features
  5. Profile-specific Test Configs: Use @ActiveProfiles with minimal test profiles

See Also

  • Test Configuration - @TestConfiguration for test-specific beans
  • Context Runners - Lightweight alternative for isolated testing
  • Test Properties - Dynamic property management