Open-Source Wikis

/

Spring Framework

/

How to contribute

/

Testing

spring-projects/spring-framework

Testing

Spring Framework has roughly 2,800 test classes across its modules. Coverage is not a metric the project chases as a number, but the expectation for new code is that it ships with tests.

Test stack

The project uses (declared in the root build.gradle):

Library Purpose
org.junit.jupiter:junit-jupiter JUnit 5 (Jupiter) — primary test runner
org.junit.platform:junit-platform-suite Test suite support
org.mockito:mockito-core, mockito-junit-jupiter Mocking
io.mockk:mockk Kotlin-friendly mocking
org.assertj:assertj-core Fluent assertions
org.junit.platform:junit-platform-launcher Test runner for tooling
org.apache.logging.log4j:log4j-core Logging during tests

JUnit 4 is not used in new tests; older test classes still using JUnit 4 are migrated as they are touched.

Where tests live

Within each module:

spring-<name>/
└── src/
    ├── main/                    # production code
    ├── test/                    # tests
    │   ├── java/                # JUnit 5 tests
    │   └── kotlin/              # Kotlin tests using MockK
    ├── testFixtures/            # shared fixtures consumable by other modules
    └── jmh/                     # JMH benchmarks (some modules)

Tests follow the package layout of the production code — a class at src/main/java/.../Foo.java is normally tested at src/test/java/.../FooTests.java. The convention is *Tests.java (plural). A few legacy classes use *Test.java.

Running tests

./gradlew test                                  # run all tests in all modules
./gradlew :spring-core:test                     # one module
./gradlew :spring-web:test --tests "*Cors*"     # filtered
./gradlew :spring-context:test --tests "org.springframework.context.annotation.ConfigurationClassParserTests"

The Gradle test report lands at <module>/build/reports/tests/test/index.html.

Categories of tests in this repo

  • Unit tests — Plain JUnit 5 tests with Mockito or hand-rolled fakes. The bulk of the suite.
  • Slice integration tests — Tests that wire up a small ApplicationContext to verify behavior across multiple beans.
  • End-to-end / cross-module testsintegration-tests/ exercises wiring across modules (e.g., spring-web with spring-test).
  • Native image tests — Some modules carry *RuntimeHintsTests that exercise the AOT processor and verify hint registration.
  • Benchmarks — JMH benchmarks live in <module>/src/jmh/ and are run separately (./gradlew :spring-core:jmh).

Test fixtures

The java-test-fixtures Gradle plugin (applied in the root build.gradle) lets a module expose test code to other modules without leaking it into the production JAR. Pattern:

// spring-context.gradle
dependencies {
    testImplementation(testFixtures(project(":spring-core")))
}

Fixtures live in <module>/src/testFixtures/java/. Examples:

  • spring-core exposes EnabledForTestGroups (gates tests by environment)
  • spring-test exposes test runners reused by other framework tests
  • spring-context exposes context-creation helpers

Mocks for the web stacks

spring-test ships:

  • MockMvc (org.springframework.test.web.servlet) — Tests Spring MVC controllers without starting a server.
  • WebTestClient (org.springframework.test.web.reactive.server) — Tests WebFlux handlers, with both bound (no network) and connected modes.
  • MockHttpServletRequest / MockHttpServletResponse — Mocks for the Servlet API.
  • MockServerHttpRequest / MockServerHttpResponse — Mocks for the reactive web stack.

These mocks are not in org.springframework.mock.* by accident — they are deliberately provided as a public testing API.

TestContext framework

The TestContext framework (in spring-test) is the heart of Spring's integration testing model:

  • @SpringJUnitConfig (or @ContextConfiguration + @ExtendWith(SpringExtension.class)) — Boot a Spring context per test class.
  • Contexts are cached by configuration. Tests with identical configuration share one context, dramatically speeding up test suites.
  • @DirtiesContext — Mark a context dirty so the cache evicts it.
  • @TestPropertySource — Layer test-specific properties.
  • @MockitoBean — Replace a bean in the context with a Mockito mock.

Common test patterns

  • Custom assertions — Modules sometimes provide AssertJ assert classes (e.g., assertThatExceptionOfType(SomeException.class)).
  • @Nested test classes group related cases under one parent (used heavily in spring-context and spring-web).
  • Parameterized tests@ParameterizedTest with @MethodSource is the favored style; @ValueSource for simple cases.
  • Disabled tests — Use @Disabled("reason and gh-NNNN"). Avoid silent skips.

Adding a test

  1. Find the module under spring-<name>/.
  2. Create a class at src/test/java/<package>/<ClassName>Tests.java (mirroring the production code path).
  3. Use JUnit 5 + AssertJ; only reach for Mockito where it's the right tool.
  4. Run ./gradlew :spring-<name>:test --tests "*<YourClass>*" to validate.

See debugging for hints when tests behave mysteriously.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Testing – Spring Framework wiki | Factory