Inside a Mockito Answer callback you are handed an InvocationOnMock object. What information and operations does it expose, and what is each one typically used for?
answer
- getArgument(i) / getArgument(i, Class)
- getArguments() for generic answers
- getMock() -> fluent builders, RETURNS_SELF
- callRealMethod() needs a real implementation
- answer(...) throws Throwable
basics
~20 sInvocationOnMock describes the current call: getArgument(i) / getArguments() for the arguments, getMethod() for the reflective method, getMock() for the mock itself (handy for fluent builders returning this), and callRealMethod() to delegate to the real implementation on a spy or partial mock.
solid answer
~50 s`InvocationOnMock` is Mockito's description of the single call that triggered your `Answer`. - `getArgument(int)` returns one argument, generically typed; `getArgument(int, Class)` makes the cast explicit; `getArguments()` gives the raw `Object[]`. - `getMethod()` returns the `java.lang.reflect.Method`, useful for generic answers shared across methods. - `getMock()` returns the mock instance. The standard use is stubbing fluent builders: `thenAnswer(inv -> inv.getMock())` so every builder call returns the same mock. - `callRealMethod()` executes the real implementation and returns its result - only meaningful on a spy or a partial mock of a class. On a plain interface mock there is no implementation, so Mockito throws. A very common pattern is invoking a callback that arrived as an argument: pull it out with `getArgument`, call it, return null. That lets you drive callback-based or async APIs synchronously in a test.
code
java · 6 linesdoAnswerStyleAside();
when(client.fetch(anyString(), any(Callback.class))).thenAnswer(invocation -> {
Callback cb = invocation.getArgument(1, Callback.class);
cb.onSuccess("payload");
return null;
});go deeper
Recall the two you use daily: getArgument(index) to read what was passed, and returning a value from the lambda.
Cover the full surface - arguments, method, mock, callRealMethod - and name a concrete use for each, especially getMock() for fluent builders.
Emphasise the constraints: callRealMethod needs a real implementation and a properly constructed instance, and generic answers branch on getMethod().
Discuss when a mock-wide default Answer is the right abstraction versus per-stub answers, and the maintenance cost of reflective answers that branch on method names.
## What the object is When Mockito routes a call to your `Answer`, it passes an `InvocationOnMock` - a snapshot of exactly one invocation. Everything you can know about that call is on this object; there is no hidden context. ## Reading arguments `getArgument(int index)` is the everyday method. It is declared with a generic return type and performs an unchecked cast, so `String s = inv.getArgument(0);` compiles fine and fails at runtime if argument 0 is not a String. The two-argument overload `getArgument(0, String.class)` states the type explicitly and reads better in review. `getArguments()` returns the whole `Object[]`. It is what you want in a generic answer that does not know the arity in advance - for example an answer shared across several methods, or one that logs the call. For varargs methods be careful: `getArguments()` may present the varargs already packed into an array element, and `getRawArguments()` exists precisely to see the un-expanded form. ## Knowing which method was called `getMethod()` returns the reflective `Method`. This matters when one `Answer` instance is installed as a mock-wide default (via `mock(Foo.class, myAnswer)`) rather than on a single stubbing: the answer must branch on `getMethod().getName()` or on `getMethod().getReturnType()` to decide what to give back. Mockito's own built-in defaults, such as the answer that returns empty collections for collection-returning methods, work exactly this way. ## Getting the mock itself `getMock()` hands back the mock the call landed on. The canonical use is a fluent API. Suppose the code under test writes `builder.withName("x").withAge(3).build()`. If `withName` and `withAge` are not stubbed, they return null and the chain NPEs. Stub them with `thenAnswer(inv -> inv.getMock())` and the chain keeps flowing on the same mock. Mockito also ships this as a ready-made default answer (`RETURNS_SELF`), which does the same thing for every method whose return type is compatible with the mock. ## Calling the real code `callRealMethod()` executes the real implementation of the invoked method with the same arguments and returns its result. It is the escape hatch that lets an answer wrap real behaviour: run the real method, then adjust, count, or delay around it. The hard constraint is that there must **be** a real implementation. On a `spy(new RealThing())` or a partial mock of a concrete class, there is. On `mock(SomeInterface.class)` or an abstract method there is not, and Mockito fails fast with a `MockitoException` complaining that it cannot call an abstract real method. A second subtlety: `mock()` instantiates without running a constructor, so real methods invoked this way see uninitialized fields. If you need real state, use a spy over a properly constructed instance. ## Exceptions from the answer `Answer.answer` is declared `throws Throwable`, so an answer may simply `throw` to simulate a failure, including one computed from the arguments ("throw if the id is negative"). Whatever it throws propagates to the caller as if the collaborator had thrown it. ## Practical patterns - Echo an argument: `inv -> inv.getArgument(0)`. - Drive a callback: `inv -> { inv.<Runnable>getArgument(1).run(); return null; }`. - Fluent builder: `inv -> inv.getMock()`. - Spy wrapper: `inv -> { Object r = inv.callRealMethod(); counter.increment(); return r; }`. - Argument-dependent failure: `inv -> { if (inv.getArgument(0, Long.class) < 0) throw new IllegalArgumentException(); return found; }`. Each of these is short. If your answer needs more than a handful of lines, prefer a named `Answer` class with a descriptive name, or reconsider whether a fake would express the intent better.
- What happens if you call invocation.callRealMethod() inside an Answer attached to mock(SomeInterface.class)?It fails with a MockitoException saying it cannot call an abstract real method, because an interface method has no body to run. callRealMethod only makes sense on a spy or a partial mock of a concrete class. If you want real behaviour, wrap a real instance with spy() instead of mocking the interface.
- Why can a real method called through callRealMethod on a mock() throw NullPointerException on its own fields?Mockito instantiates class mocks without running any constructor, so instance fields are left at their default null/0 values. The real method then dereferences an uninitialised field. A spy over an object you constructed yourself does not have this problem, because the object was fully built before it was wrapped.
saying these in an interview costs you the question
- Thinking getArgument is type-checked at compile time
- Expecting callRealMethod to work on an interface mock
- Assuming getArguments always shows varargs expanded the way the caller wrote them
- Believing the Answer cannot throw - it is declared throws Throwable
- Using getMock() to re-stub the mock from inside the answer instead of returning it