Software Development
Java Testing and TDD with JUnit 5
A working course on Java testing for teams whose suite is slow, brittle, or quietly ignored. Participants write tests with JUnit 5, isolate collaborators with Mockito, exercise real dependencies through Testcontainers, and practise the test-driven cycle on features that resemble their own backlog.
Overview
Practical learning for workplace transfer.
A test suite fails a team in one of two ways: it breaks whenever code is refactored, or it stays green while defects reach customers. Both come from asserting implementation details instead of behaviour, and both end the same way, with a team that skips the suite to make a deadline. This course rebuilds the discipline of deciding what to assert, what to isolate, and what to leave real, using JUnit 5 capabilities most teams never adopt: parameterized and nested tests, lifecycle control, grouped assertions, and tagged execution. Participants practise red-green-refactor on new work and learn how to introduce tests around code written without any.
Prerequisites
Practical Java development experience and familiarity with Maven or Gradle. No prior JUnit 5 experience is required.
Objectives
- Write expressive JUnit 5 tests using parameterized, nested, and tagged structures.
- Distinguish stubs, mocks, fakes, and spies, and use Mockito without over-specifying behaviour.
- Test data access and messaging against real dependencies using Testcontainers.
- Practise the red-green-refactor cycle on both new features and defect fixes.
- Design tests that assert behaviour so refactoring improves code without breaking the suite.
- Set coverage, execution time, and flakiness targets a build pipeline can enforce.
Target audience
- Java developers accountable for the tests that ship with their code
- Test automation engineers working inside Java codebases
- Technical leads raising the quality bar on an inherited test suite
- QA engineers moving from manual checks to code-level tests
- Teams introducing continuous integration for a Java product
- Developers maintaining modules with little or no existing coverage
Program outline
A clear structure for the learning journey.
Program outline
Outline points are grouped in one designed block instead of being treated as separate module cards.
Module 1: What to Test, and Why Suites Rot
Separating the responsibilities of unit, integration, and end-to-end tests
Behaviour versus implementation, and why the difference decides suite lifespan
Naming and arrangement that let a test read as a specification
The economics of a slow suite and the moment teams start bypassing it
Module 2: JUnit 5 in Depth
The Jupiter lifecycle, extensions, and the migration path from JUnit 4
Parameterized tests driven by value, CSV, enum, and method sources
Nested tests, display names, and assumptions for conditional execution
Grouped assertions, exception assertions, timeouts, and tag-based selection
Module 3: Test Doubles and Mockito
Stubs, mocks, fakes, and spies: choosing the weakest double that works
Mockito stubbing, argument matchers, and verification without over-specifying
Designing for testability through injection, pure functions, and small seams
Mocking boundaries you own, and never mocking types you do not control
Module 4: Integration Testing with Testcontainers
Running databases, brokers, and dependencies as disposable containers
Spring Boot test slices weighed against full application context tests
Deterministic test data, isolation between tests, and a cleanup strategy
Keeping integration tests fast enough to run on every commit
Module 5: Test-Driven Development in Practice
Applying red-green-refactor to a feature with real acceptance criteria
Letting tests drive a design without freezing the implementation too early
Reproducing a reported defect as a failing test before repairing it
Where TDD pays, where it slows delivery, and how to make that call
Module 6: Legacy Code, Coverage, and the Pipeline
Characterization tests that pin existing behaviour before it is changed
Finding seams and refactoring safely to make untestable code testable
Reading coverage honestly: what the number does and does not prove
Flaky test triage, execution time budgets, and continuous integration gates
Materials provided
- Course workbook, annotated code samples, and reference notes
- Hands-on lab environment and starter repositories
- Exercises, checklists, and reusable code templates
- 4D Certificate of Completion
- Post-course technical guidance
Training Options
Programs can be delivered in-house, online, or in a blended format depending on your team's schedule, location, and learning objectives. When an external certificate or exam is included, certification rules and fees remain under the relevant awarding body's policies, while 4D provides the training and preparation support.
Why choose 4D
4D runs this course against a codebase carrying the same testing problems as yours: legacy classes without seams, mocks that assert far too much, and integration tests too slow to run on a commit. Participants leave with a written suite policy covering execution time, flaky test handling, and pipeline gates the team agreed rather than inherited.
Related courses
Python Programming Fundamentals
A hands-on introduction to Python for engineers and analysts who need working code rather than tutorial fragments. Participants build fluency with data types, collections, functions, files, and error handling, then assemble a small program that reads real data and produces a usable report.
View courseIntermediate Python and Clean Code Practices
Designed for developers whose Python works but is difficult to change. The course covers dataclasses, generators, decorators, context managers, and type hints, then applies the refactoring moves that turn a nine-hundred-line module into small tested units guarded by black, ruff, and mypy.
View coursePython Automation and Scripting for Work Tasks
Aimed at teams losing hours every week to repetitive file, spreadsheet, and reporting work. Participants automate those tasks with Python: batch file handling, Excel and CSV processing, REST API calls, email alerts, and scheduled jobs that run unattended and report clearly when something fails.
View course