Spring: TDD With JUnit

This course teaches how to test a Spring application at different layers. The course uses Junit 4, but I use Jnunit 5 in any code representations below.

Why TDD Matters

  • Quick design validation and feedback

  • Tests become executable documentation and acceptance criteria

  • Change management

  • Team member onboarding and training

Testing Service Components

The service layer is typically the most business logic heavy layer and is where test coverage is needed the most.

Test Planning

Have a plan before writing tests:

  1. What features need most coverage?

  2. What are the high priority test cases?

  3. What type of tests are required? (Unit, Integration, behaviour etc)

Service Integration Tests

Setup a service integration tests by instructing Junit to do:

  • Only load @Service annotations and dependencies

  • Connect to required data source

  • Don't load unnecessary components such as @RestController

Example test from the course:

Service Unit Tests

When unit testing your methods in a service class, you isolate your testing to that class only and don't need to worry about other dependencies should as data persistence. To achieve this you'll need to use mocks to 'mock' required dependencies.

Testing Controller Components

Test Planning

  1. What features need most coverage?

  2. What are the high priority test cases?

  3. What type of tests are required? (Unit, Integration, behaviour etc)

  4. What kind of @Controllers are involved: MVC, RESTful, or both?

The main difference between the types of controllers is the output that they send back. MVC returns ViewModel objects, whereas RESTful returns JSON or XML.

The following examples are for MVC controllers.

Controller Integration Tests

Initial setup preview: 1. Load full web environment 2. Load @Controller 3. Load @Service 4. Load @Repository

Controller Unit Tests

Initial setup preview: 1. Mock web browser behaviour 2. Load @Controller 3. Load mocks for @Service

Testing Repository Components

Test Planning

  1. What features need most coverage?

  2. What are the high priority test cases?

  3. What type of tests are required? (Unit, Integration, behaviour etc)

  4. What type of persistence layer: relational, graph or both

NOTE: There's not a lot of ROI for unit testing repository as it's the Spring framework that provides alot of what could be called, the units. The following will focus only on an integration test.

Repository Integration Test

Initial setup preview: 1. Not load @Controller or @Service 2. Load @Respository and related dependencies 3. Load JPA testing configs

The @DataJpaTest annotation bundles the following: @AutoConfigureDataJpa, @AutoConfigureTestDatabase, @AutoConfigureTestEntityManager, @Transactional and more.

  1. @AutoConfigureDataJpa - imports config needed for JPA testing.

  2. @AutoConfigureTestDatabase - Setup for rquired db. Can use embedded, external or staging for example.

  3. @AutoConfigureTestEntityManager - Allows direct access to the EntityManager.

  4. @Transactional - allows us to have rollback behaviour after test executions.

As with all of the examples above, start with the happy path test scenario and then extend with further test scenarios to ensure you build out your components in a test driven way.

Last updated

Was this helpful?