mockito/mockito · error · NeverWantedButInvoked

${wanted} Never wanted here: ${location} But invoked here: $

Error message

${wanted}
Never wanted here:
${location}
But invoked here:
${locations with arguments}

What it means

Mockito's never() verification failed: the test marked a method as never wanted (times(0)), but it was invoked at least once. NumberOfInvocationsChecker throws NeverWantedButInvoked, listing the location and arguments of each offending invocation so the developer can see exactly which call should not have happened.

Source

Thrown at mockito-core/src/main/java/org/mockito/internal/verification/checkers/NumberOfInvocationsChecker.java:43

import org.mockito.invocation.Location;
import org.mockito.invocation.MatchableInvocation;

public class NumberOfInvocationsChecker {

    private NumberOfInvocationsChecker() {}

    public static void checkNumberOfInvocations(
            List<Invocation> invocations, MatchableInvocation wanted, int wantedCount) {
        List<Invocation> actualInvocations = findInvocations(invocations, wanted);

        int actualCount = actualInvocations.size();
        if (wantedCount > actualCount) {
            List<Location> allLocations = getAllLocations(actualInvocations);
            throw tooFewActualInvocations(
                    new Discrepancy(wantedCount, actualCount), wanted, allLocations);
        }
        if (wantedCount == 0 && actualCount > 0) {
            throw neverWantedButInvoked(wanted, actualInvocations);
        }
        if (wantedCount < actualCount) {
            throw tooManyActualInvocations(
                    wantedCount, actualCount, wanted, getAllLocations(actualInvocations));
        }

        markVerified(actualInvocations, wanted);
    }

    public static void checkNumberOfInvocations(
            List<Invocation> invocations,
            MatchableInvocation wanted,
            int wantedCount,
            InOrderContext context) {
        List<Invocation> chunk = findMatchingChunk(invocations, wanted, wantedCount, context);

        int actualCount = chunk.size();

View on GitHub (pinned to 5a676bcd9e)

Solutions

  1. Inspect the 'But invoked here' locations/arguments in the message to identify which code path made the forbidden call.
  2. Fix the code under test so the forbidden path is not executed (guard clauses, early returns, correct configuration).
  3. If the call is actually legitimate now, update the test: replace never() with times(n) or atLeastOnce().
  4. Check stubbing: an incorrectly stubbed method or a spy calling real code can trigger unexpected invocations; use doReturn().when() on spies instead of when().

Example fix

// before
verify(payments, never()).charge(any()); // but refund path also charges

// after: fix code so only refund logic runs, or update expectation
verify(payments, times(1)).charge(any());
Defensive patterns

Strategy: try-catch

Validate before calling

long actual = Mockito.mockingDetails(mock).getInvocations().stream()
    .filter(i -> i.getMethod().getName().equals("charge")).count();
if (actual > 0 && expectingNoCharge) throw new AssertionError("forbidden charge() executed " + actual + "x");

Try / catch

try {
    verify(payments, never()).charge(any());
} catch (NeverWantedButInvoked e) {
    // message lists the offending call site — route to failure diagnostics
    throw new AssertionError("forbidden path executed: " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: verify(mock, never()).method(); verify(mock, times(0)).method(); verifyNoMoreInteractions-style flows hitting the wantedCount == 0 && actualCount > 0 branch in checkNumberOfInvocations.

Common situations: Testing an error/fallback path but the happy path still ran; a retry loop still fired the call the test thought was suppressed; verifying the wrong argument matcher so a legitimate call registers as the forbidden one; regression where new code added a call that a safety-net test forbids.

Related errors


AI-assisted analysis of mockito/mockito@5a676bcd9e (2026-09-05). Data as JSON: /api/errors/2825e79a050a1e56. Report an issue: GitHub.