October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run ScanOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk5 min

JUnit 5 and Mockito Tutorial: How to Write Unit Tests

A practical guide to JUnit Jupiter test structure, selective Mockito stubbing and verification, and using MockitoExtension with JUnit 5.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Write a JUnit 5 test by marking a method with Jupiter’s @Test, calling the code under test, and asserting its result. Add Mockito only when a collaborator needs a controlled response or an interaction is part of the behavior you want to specify. For Jupiter tests, register Mockito’s extension with @ExtendWith(MockitoExtension.class) so it initializes annotated mocks.

What JUnit 5 means

JUnit 5 is an umbrella for three parts: the JUnit Platform, which provides the foundation for running test engines; JUnit Jupiter, the programming and extension model used to write contemporary JUnit tests; and JUnit Vintage, which supports running tests written for older JUnit versions. In this tutorial, “JUnit 5 test” means a JUnit Jupiter test. See the JUnit 5 User Guide for the architecture and APIs.

How do I write a basic JUnit 5 test?

A test follows arrange, act, assert: prepare inputs, call the method, and check the outcome. This example tests a small deterministic calculation without a mock:

import static org.junit.jupiter.api.Assertions.assertEquals;

import org.junit.jupiter.api.Test;

class CalculatorTest {
    @Test
    void addsTwoNumbers() {
        Calculator calculator = new Calculator();

        int result = calculator.add(2, 3);

        assertEquals(5, result);
    }
}

The production Calculator class must provide add(int, int). The test method is discovered through Jupiter’s @Test; assertEquals(expected, actual) fails the test if the values differ. JUnit’s guide introduces this test shape and assertion style in its starter examples.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use lifecycle and parameterized tests when they help

Use @BeforeEach for setup that should run separately before each test, rather than sharing mutable state that can make test outcomes order-dependent. Use @ParameterizedTest with a suitable argument source when the same behavior needs checking against several input sets; the current JUnit guide describes the argument-source options and modules.

When should I use a real object or a mock?

Use ordinary real objects for data and simple deterministic logic. A mock is useful when a unit collaborates with something whose response should be controlled for this test, or when an important interaction itself belongs to the behavior being specified. For example, a payment service might depend on a payment gateway; the test can make the gateway return an approved result without calling a real external service.

Do not mock a dependency simply because it is injectable. Excessive mocks can make a test describe internal wiring rather than meaningful behavior. Mockito’s documentation covers mock creation, stubbing, and verification, and cautions against mocking ordinary collection implementations in production tests: Mockito API documentation.

How do I use Mockito with JUnit 5?

Add the mockito-junit-jupiter integration artifact matching the Mockito version selected for your project, along with JUnit Jupiter. The exact dependency versions and Java compatibility depend on the project’s build and selected releases; check the release metadata and compatibility before copying version numbers. The code below demonstrates the test structure, not a claim that one dependency version fits every project.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Register MockitoExtension on a Jupiter test class with @ExtendWith. The extension initializes @Mock fields and provides strict stubbing behavior. JUnit’s extension registration is described in its ExtendWith API; the surfaced Mockito extension API is documented for Mockito JUnit Jupiter 4.11.0. That version-specific page is integration evidence, not a recommendation to use that version with every project.

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
class PaymentServiceTest {
    @Mock
    PaymentGateway gateway;

    @Test
    void returnsApprovedWhenGatewayApproves() {
        PaymentRequest request = new PaymentRequest("order-17");
        when(gateway.charge(request)).thenReturn(PaymentResult.approved());
        PaymentService service = new PaymentService(gateway);

        PaymentResult result = service.pay(request);

        assertEquals(PaymentResult.approved(), result);
        verify(gateway).charge(request);
    }
}

This example assumes the project defines PaymentGateway, PaymentRequest, PaymentResult, and PaymentService with the shown methods and compatible equality behavior. It illustrates the pattern rather than an executed test. The result assertion is the primary check; the verification is useful if making that gateway call is itself part of the service’s specified behavior.

Rank #4
Sale

Stub only what the test needs

when(gateway.charge(request)).thenReturn(result) arranges a predictable response. Keep setup focused on the scenario under test. Do not add stubs for behavior the test never exercises.

Use matchers consistently

When a Mockito invocation uses argument matchers, use matchers for all arguments in that invocation rather than mixing matcher calls with raw values. Consult the API for the version in your build to confirm matcher details and method names.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Best Value

Void methods and spies need a different stubbing form

For void methods, spies, or situations where when(...) would invoke a real spy method while arranging the stub, consult Mockito’s doReturn, doThrow, and related APIs instead of applying the ordinary when(...).thenReturn(...) pattern mechanically.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Should I assert behavior or verify interactions?

Assert the return value or another observable outcome by default. Add verify(...) when the collaboration is part of the behavior you mean to guarantee—for instance, that a payment request is sent to the gateway. Routine exhaustive checks such as verifyNoMoreInteractions() can overspecify implementation details and make otherwise valid refactoring break tests. Mockito documents verification and warns against excessive interaction checks in its API guidance.

Common problems and fixes

  • Mockito annotations are not initialized: for Jupiter, register @ExtendWith(MockitoExtension.class) and ensure the matching mockito-junit-jupiter artifact is on the test classpath.
  • The extension or mockito package cannot be resolved: check that the Jupiter integration dependency is included and that its version matches the Mockito core version selected by the project.
  • A stub is reported as unused: strict stubbing can expose setup that the test does not use. Remove the unnecessary stub or correct the test path so it exercises the intended call.
  • A test fails after adding matcher syntax: use matchers for every argument in that invocation, not a mixture of matcher and raw arguments.
  • A spy calls real behavior while stubbing: use the appropriate Mockito doReturn/doThrow family for that case, after checking the selected version’s API.
  • Tests pass individually but interfere when run together: avoid mutable shared test state; put per-test initialization in @BeforeEach when appropriate.

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server for developers. For one clean screenshot request:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo API documentation. It accepts cookie and consent banners before capture and removes 60+ known consent platforms, newsletter popups, and chat widgets; those steps can be disabled. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers identify the page verdict and billing status. Its MCP server gives AI agents tools for screenshots, page information, and PDFs. The free plan includes 1,000 shots a month with no card; paid plans start at $5 for 3,000 shots.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Sign up for 1,000 free screenshots a month with no card.

Quick Recap

SaleBestseller No. 3
SaleBestseller No. 4
Pragmatic Unit Testing in Java with JUnit
Pragmatic Unit Testing in Java with JUnit
Used Book in Good Condition
$13.55
SaleBestseller No. 5

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. Shenzhen desk3 min
    HONOR Expands Beyond Smartphones With Humanoid Robot RevealHONOR said it unveiled its first humanoid robot at MWC 2026 and named shopping assistance, workplace inspections, and supportive companionship as intended uses. Later Robotics D1 claims and a reported…
  2. Cupertino desk5 min
    Apple Unveils AirPods Max 2: The Upgrade That Should Have Happened Years AgoAirPods Max 2 adds H2-powered audio features and Apple claims up to 1.5× more effective ANC, but its design, Smart Case, and 20-hour battery rating are unchanged. Wired lossless audio…
  3. Cupertino desk4 min
    Apple’s OLED Touch MacBooks Are Coming—but the Dynamic Island Is the Real GambleApple has not announced an OLED touchscreen MacBook, but reports point to high-end models arriving in late 2026 or early 2027. The reported Mac Dynamic Island could be useful, but…
Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.