Appearance
Unit Testing Roadmap: JUnit 5 and Mockito
Unit testing means testing one small piece of code, typically a single method, in isolation, to check that it works as expected. It is not integration testing or functional testing; those check how pieces work together.
This series assumes Core Java: classes, interfaces, annotations, generics, lambdas and exceptions.
The tools
A testing framework runs your tests and reports the results. The common Java choices are JUnit and TestNG; JUnit is by far the most widely used, and this series uses JUnit 5: its annotations, its assertions, and how to repeat, parameterize, group and extend tests.
A mocking framework. A method rarely works alone. Say a method in class A calls a method in class B:
java
public class A {
private final B b;
public A(B b) {
this.b = b;
}
public String process() {
boolean ok = b.check(); // depends on B
return ok ? "done" : "failed";
}
}To test process() in isolation, you do not want the real B (it may call a database or another service). You replace it with a mock: a stand-in whose answers you choose ("when check() is called, return true"). JUnit has no mocking of its own, so it is combined with a mocking framework. The popular ones are Mockito and EasyMock (JMock is another); this series uses Mockito.
The path through the series
Read the chapters in order: each one uses what the earlier ones built.
| Module | Chapters | What you will be able to do |
|---|---|---|
| 1. Foundations | 1–3 | Say what a unit test is and how it differs from integration and functional tests; explain how JUnit 5 (Platform, Jupiter, Vintage) runs your tests. |
| 2. Writing tests | 4–5 | Set up a project, use the lifecycle methods and test instances, run tests in parallel, follow the AAA pattern, and check results with assertions, including exceptions and timeouts. |
| 3. Extending JUnit | 6 | Hook your own code into JUnit with extensions: callbacks, parameter resolvers, conditions, interceptors. |
| 4. Repeated and parameterized tests | 7–9 | Run a test several times, or once per input from values, enums, CSV, methods and providers. |
| 5. Assumptions and selecting tests | 10–12 | Skip a test when its preconditions do not hold, tag tests and run a selection, and group tests into suites. |
| 6. Dynamic tests | 13 | Create tests at run time with @TestFactory. |
| 7. Mockito fundamentals | 14–15 | Tell mocks, stubs and spies apart, and know how Mockito makes them work. |
| 8. Mockito with JUnit 5 | 16–17 | Create mocks with @Mock, @Spy and @InjectMocks through MockitoExtension, as fields or as parameters. |
| 9. Stubbing and verification | 18–19 | Stub any method, with matchers and dynamic answers, and verify how a dependency was used. |
Mockito can mock static methods and constructors, but not private methods: a private method is tested through the public method that calls it.
Beyond this series
Two related topics are not covered here: AssertJ, an assertion library with a fluent, chainable API for complex checks; and code coverage with JaCoCo, which measures how much of the code the tests exercise.
Next: Chapter 2 makes "unit test" precise: what a unit is, what testing it in isolation means, and how unit tests differ from integration and functional tests.
Check yourself
- What is unit testing, and what does "in isolation" mean?
- Why does JUnit need a separate mocking framework?
- What is a mock, in one sentence?
- Name two Java testing frameworks and two mocking frameworks.
Answers
- Testing one small piece of code, usually a method, on its own; its dependencies are replaced so only that code is tested.
- JUnit runs tests and checks results but cannot create stand-ins for dependencies.
- A stand-in for a real dependency, whose behavior the test controls.
- JUnit and TestNG; Mockito and EasyMock.