mockito/mockito · error · NotAMockException

Argument passed to when() is not a mock! Example of correct

Error message

Argument passed to when() is not a mock!
Example of correct stubbing:
    doThrow(new RuntimeException()).when(mock).someMethod();

What it means

StubberImpl.when(mock) received a non-null object that is not a Mockito mock (or spy). isMock(mock) fails, state is reset, and notAMockPassedToWhenMethod() is thrown. The doXxx().when(obj) form only works on mocks/spies created by Mockito.

Source

Thrown at mockito-core/src/main/java/org/mockito/internal/stubbing/StubberImpl.java:45

    private final Strictness strictness;

    public StubberImpl(Strictness strictness) {
        this.strictness = strictness;
    }

    private final List<Answer<?>> answers = new LinkedList<>();

    @Override
    public <T> T when(T mock) {
        if (mock == null) {
            mockingProgress().reset();
            throw nullPassedToWhenMethod();
        }

        if (!isMock(mock)) {
            mockingProgress().reset();
            throw notAMockPassedToWhenMethod();
        }

        MockUtil.getInvocationContainer(mock).setAnswersForStubbing(answers, strictness);

        return mock;
    }

    @Override
    public Stubber doReturn(Object toBeReturned) {
        return doReturnValues(toBeReturned);
    }

    @Override
    public Stubber doReturn(Object toBeReturned, Object... nextToBeReturned) {
        return doReturnValues(toBeReturned).doReturnValues(nextToBeReturned);
    }

    private StubberImpl doReturnValues(Object... toBeReturned) {

View on GitHub (pinned to 5a676bcd9e)

Solutions

  1. Pass a mock created via Mockito.mock(...), @Mock, or Mockito.spy(...) — not a plain instance.
  2. If you need partial stubbing on a real object, wrap it with Mockito.spy(realObject) first.
  3. Verify the object identity: it must be the same instance that is injected into the code under test.

Example fix

// before
UserRepository real = new InMemoryUserRepository();
doThrow(new IOException()).when(real).save(any());
// after
UserRepository repo = spy(new InMemoryUserRepository());
doThrow(new IOException()).when(repo).save(any());
Defensive patterns

Strategy: type-guard

Validate before calling

if (!Mockito.mockingDetails(candidate).isMock()) throw new IllegalArgumentException("expected a Mockito mock or spy");

Type guard

static boolean isMockitoMock(Object o) { return o != null && Mockito.mockingDetails(o).isMock(); }

Prevention

When it happens

Trigger: doThrow(x).when(realObject).method(); passing a stub/fake implementation, a builder-produced object, or an interface implementation hand-written in the test; passing a Mockito-mocked class but a different wrapped instance (e.g. after deserialization or a proxy wrapper).

Common situations: Mixing hand-rolled fakes with Mockito stubbing; accidentally stubbing the system-under-test instead of its collaborator; Spy on an object later re-wrapped; using a mock created by another mocking framework (EasyMock) with Mockito APIs.

Related errors


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