What does Mockito's thenCallRealMethod() do, when is it the right tool, and what surprises people about using it on an object created with Mockito.mock() rather than spy()?
answer
- Partial mock: one method real, rest mocked
- mock() uses Objenesis - no constructor, fields null
- spy(new Foo()) when real state is needed
- Abstract / interface methods: cannot call real
- Partial mocks = design smell, fine for abstract bases
basics
~20 sthenCallRealMethod() makes one stubbed method execute its real body instead of returning a default, creating a partial mock. The surprise: mock() builds the instance without running a constructor, so fields are uninitialised and real methods often hit NullPointerException - spy() over a constructed object avoids that.
solid answer
~50 s`when(obj.compute()).thenCallRealMethod()` routes that one method to the real implementation while everything else on the mock keeps returning defaults. The classic use is testing a concrete method on an abstract class without writing a subclass, or letting one template method run while its hooks stay mocked. Two constraints matter. - There must **be** an implementation. On an interface method with no default body, or an abstract method, Mockito fails at call time. - `Mockito.mock(Foo.class)` instantiates via Objenesis **without calling any constructor**, so instance fields are null/0. A real method that touches them typically NPEs. `spy(new Foo(...))` wraps a properly constructed object and does not have this problem. Beyond abstract-class testing, treat partial mocks as a smell: a class that needs half of itself mocked is usually two classes. `thenCallRealMethod` is also useful inside a custom `Answer` via `invocation.callRealMethod()` when you want to wrap real behaviour.
code
java · 12 linesclass Greeter {
private final String name;
Greeter(String name) { this.name = name; }
String greet() { return "hi " + name.toUpperCase(); }
}
Greeter m = mock(Greeter.class);
when(m.greet()).thenCallRealMethod();
m.greet(); // NullPointerException: no constructor ran, name is null
Greeter s = spy(new Greeter("ada"));
assertEquals("hi ADA", s.greet()); // real object, real statego deeper
Say what it does - the real method body runs instead of returning a default - and that spy() is the usual way to get real behaviour.
Explain the abstract-class use case and the constructor surprise: mock() skips constructors, so fields are null and real methods can NPE.
Position partial mocks as a design smell with narrow legitimate uses, and choose deliberately between spy, delegatesTo, and constructing the real object.
Argue about testability as a design property: needing to mock part of a class is evidence of a missing seam, and the refactor usually beats the framework feature.
## What it does A mock's methods normally do nothing and return a default. `thenCallRealMethod()` overrides that for one stubbing: when a matching call arrives, Mockito invokes the class's actual implementation with the actual arguments and returns its result. The object becomes a **partial mock** - real for that method, mocked for everything else. ```java when(calculator.total()).thenCallRealMethod(); ``` ## The legitimate use cases **Abstract classes.** You want to test a concrete method on an abstract base without writing a throwaway subclass in the test: ```java AbstractJob job = mock(AbstractJob.class); when(job.describe()).thenCallRealMethod(); // real concrete method // abstract doWork() stays mocked ``` **Template methods.** Let the orchestrating method run for real while its overridable hooks stay stubbed, so you can assert on the ordering of hook calls. **Interface default methods.** A `default` method has a body, so it can be called for real while the abstract methods it relies on are stubbed. **Wrapping inside an Answer.** `invocation.callRealMethod()` is the same mechanism, letting an answer run the real behaviour and then count, delay, or adjust the result. ## The constructor surprise This is the part interviews probe. `Mockito.mock(Foo.class)` does not construct a `Foo`. It generates a subclass and instantiates it through Objenesis, which allocates the object **without running any constructor** - not `Foo`'s, not its superclass's. Every instance field therefore holds its default value: object fields `null`, numeric fields `0`, `boolean` fields `false`, and any `final` field assigned in a constructor or initialiser is also unset. So a real method invoked via `thenCallRealMethod()` on a `mock()` sees an object that no constructor ever prepared. `return this.name.toUpperCase()` throws NullPointerException; `this.items.size()` throws; a field-injected collaborator is null. The fix is to use `spy(new Foo(dep))`, which wraps an object you constructed normally - all fields initialised - and makes real behaviour the default rather than the exception. If you must use `mock()`, you can inject state reflectively (for example with a test utility that sets fields), but that is a workaround, and a signal you wanted a spy. ## When the real method cannot be called - **Abstract methods and plain interface methods** have no body. Mockito raises a `MockitoException` explaining it cannot call an abstract real method. If you actually want default behaviour there, stub a value instead. - **Final methods** are not intercepted by the default subclass mock maker, so a stubbing on them does not take effect at all; the real method simply runs and your stubbing configuration is unusable. ## Partial mocks as a design signal Mockito's own documentation is candid: partial mocks were once considered a code smell and are supported for legacy and specific cases. The reasoning holds. If a test must mock half of a class to exercise the other half, the class is doing two jobs, and the honest refactor is to extract the mocked half into a collaborator that can be injected and mocked cleanly. Testing a class against a modified version of itself also weakens the test: it can pass while the real, unmodified object would fail. Acceptable uses in practice: an abstract base class you own but cannot instantiate; a third-party class you cannot restructure; instrumenting real behaviour inside an `Answer`. ## Choosing between the options - Need real behaviour with real state -> `spy(new Foo(...))`. - Need one concrete method of an abstract class, no state involved -> `mock(Abstract.class)` plus `thenCallRealMethod()`. - Need real behaviour plus extra instrumentation -> an `Answer` calling `invocation.callRealMethod()`. - Need real behaviour for most methods but want verification separated from the object -> a fake delegated to via `delegatesTo`. Be ready to say, in one sentence, why you did not just construct the real object: often that is the answer the interviewer is fishing for.
- When would you prefer spy() over mock() plus thenCallRealMethod()?Whenever the real behaviour depends on instance state. spy() wraps an object you constructed yourself, so all fields are initialised, and real behaviour is the default with mocking as the exception - the opposite emphasis from mock() plus thenCallRealMethod(). Reserve the mock() form for abstract classes you cannot instantiate, or for stateless methods.
saying these in an interview costs you the question
- Assuming mock() runs the class constructor, so fields are initialised
- Expecting thenCallRealMethod to work on an interface method with no default body
- Using partial mocks routinely instead of extracting the mocked half into a collaborator
- Believing a stubbing on a final method takes effect with the default mock maker
- Thinking thenCallRealMethod turns the whole object into a spy rather than just that stubbing