mockito/mockito · error · UnfinishedStubbingException

Unfinished stubbing detected here: ${location} E.g. thenRet

Error message

Unfinished stubbing detected here:
${location}

E.g. thenReturn() may be missing.
Examples of correct stubbing:
    when(mock.isOk()).thenReturn(true);
    when(mock.isOk()).thenThrow(exception);
    doThrow(exception).when(mock).someVoidMethod();
Hints:
 1. missing thenReturn()
 2. you are trying to stub a final method, which is not supported
 3. you are stubbing the behaviour of another mock inside before 'thenReturn' instruction is completed, possibly on another thread

What it means

Mockito detects that a stubbing sequence started with when(...) or doXxx(...).when(mock) was never completed. When validateState() runs (at the next mock interaction such as verify or a new stubbing), MockingProgressImpl finds stubbingInProgress still set and reports the location where the incomplete stubbing began. Usually the chain was interrupted by an exception, a misplaced call, or code that invoked another mock inside the stubbing chain.

Source

Thrown at mockito-core/src/main/java/org/mockito/internal/progress/MockingProgressImpl.java:119

        verificationMode = null;
        return temp;
    }

    @Override
    public void stubbingStarted() {
        validateState();
        stubbingInProgress = LocationFactory.create();
    }

    @Override
    public void validateState() {
        validateMostStuff();

        // validate stubbing:
        if (stubbingInProgress != null) {
            Location temp = stubbingInProgress;
            stubbingInProgress = null;
            throw unfinishedStubbing(temp);
        }
    }

    private void validateMostStuff() {
        // State is cool when GlobalConfiguration is already loaded
        // this cannot really be tested functionally because I cannot dynamically mess up
        // org.mockito.configuration.MockitoConfiguration class
        GlobalConfiguration.validate();

        if (verificationMode != null) {
            Location location = verificationMode.getLocation();
            verificationMode = null;
            throw unfinishedVerificationException(location);
        }

        getArgumentMatcherStorage().validateState();
    }

View on GitHub (pinned to 5a676bcd9e)

Solutions

  1. Complete the stubbing chain with thenReturn(...), thenThrow(...), or thenAnswer(...).
  2. If the method is final (or private/static), stop stubbing it or use the mockito-inline/mock maker that supports it.
  3. Remove or hoist any calls to other mocks that happen inside the when(...) argument list; compute those values before when().
  4. Ensure each thread stubs its own mocks; don't share mock state across threads.
  5. Check that no exception/early return occurs between when(...) and thenReturn(...) in refactored code.

Example fix

// before
when(userRepo.findById(1L)); // unfinished
// after
when(userRepo.findById(1L)).thenReturn(Optional.of(user));
Defensive patterns

Strategy: validation

Validate before calling

if (!mock.getClass().getMethod("isOk").getModifiers() isFinalIgnored) { /* ensure every when(...) line is followed by a then*/ } // simple habit: write when(mock.x()).thenReturn(v) on one line

Prevention

When it happens

Trigger: Calling when(mock.someMethod()) without thenReturn/thenThrow/thenAnswer; stubbing a final method (when() silently fails to intercept); nesting a mock call (e.g. a getter on another mock) inside when() arguments; concurrent stubbing on multiple threads; an exception thrown between when() and thenReturn.

Common situations: Stubbing final classes/methods without mockito-inline; IDE autocompleting when(mock) but never adding thenReturn; helpers that call other mocks while a stubbing is in progress; JUnit tests lacking MockitoExtension that would otherwise surface the error earlier; parallel tests sharing mocks.

Related errors


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