Mocking An Entire Class

ID

java.mocking_entire_class

Severity

high

Remediation Complexity

hard

Remediation Risk

low

Remediation Effort

medium

Resource

Reliability

Language

Java

Tags

mockito, reliability, testing

Description

Disabled by default. Stubbing every method of a type says nothing about whether the subject under test is exercised: in a review of real projects the fully stubbed type was a collaborator and the subject a different class in every case. Reporting that correctly would require knowing that the mocked type is the type under test, which this rule cannot determine.

Mockito lets a test stub any subset of a class’s methods, but when a test ends up stubbing every accessible method of the mocked class, the mock has become a full stand-in for the real type. At that point the test is only exercising the stub program it just wrote — it can never fail for the reason it claims to test, because nothing in the class under test actually runs.

This rule reports a mock(X.class) whose mock object has every non-private method of X stubbed, in the same method, through when(…​)/given(…​). A class with a single non-private method is not reported: with only one member there is no "rest of the class" left unstubbed.

Rationale

interface PaymentGateway {
  boolean charge(String cardToken, int amountCents);
  String refund(String transactionId);
}

@Test
void refundsAfterAFailedCharge() {
  PaymentGateway gateway = mock(PaymentGateway.class);           // Noncompliant
  when(gateway.charge("tok", 500)).thenReturn(false);
  when(gateway.refund("txn")).thenReturn("REF-1");

  // everything below runs entirely against the stub program above
}

Both methods of PaymentGateway are stubbed, so gateway behaves exactly as this test tells it to and nothing else — there is no real PaymentGateway implementation left to fail.

Remediation

Either use a real (or purpose-built test) implementation of the class instead of mocking it entirely, or split the stubbing across separate, focused tests so each one only mocks the single method it actually needs.

@Test
void chargeIsAttempted() {
  PaymentGateway gateway = mock(PaymentGateway.class);
  when(gateway.charge("tok", 500)).thenReturn(false);
  // ...
}

@Test
void refundIsIssued() {
  PaymentGateway gateway = mock(PaymentGateway.class);
  when(gateway.refund("txn")).thenReturn("REF-1");
  // ...
}

Limitations

The mocked class is very often declared in another file, so its member list is read from the project-wide type model rather than the current compilation unit. A mock whose type has no entry in that model — a third-party type, or a scan where the model was not built — is never reported, since an unresolved member list would otherwise read as "everything is stubbed" for a class this rule cannot actually see. Only the class’s own declared methods are considered, not methods reached only through a supertype. Stubbing through Mockito’s doReturn(…​).when(mock).method() form is not counted toward "stubbed", only when(…​)/given(…​).

© 2026 Xygeni. All rights reserved