Mockito's mock() has an overload that takes a MockSettings built by withSettings(). Which of those settings do you actually use, and what problem does each one solve?
answer
- withSettings() -> MockSettings -> mock(Class, settings)
- name = readable failure messages
- defaultAnswer = smart nulls / deep stubs / RETURNS_SELF
- lenient = per-mock escape from unused-stub failure
- extraInterfaces / serializable / stubOnly = legacy, session, memory
basics
~20 sThe ones that earn their keep: name(...) for readable failure messages, defaultAnswer(...) to change what unstubbed calls return, lenient() to exempt one mock from unused-stub checking, extraInterfaces(...) when code casts the collaborator to another type, plus serializable(), stubOnly() and verboseLogging() for narrower cases.
solid answer
~50 s`withSettings()` builds a `MockSettings` you pass as the second argument to `mock()`, and most options also exist as `@Mock` attributes. - **`name("orderRepo")`** — the mock's `toString()` and every failure message use it. Essential when a test holds two mocks of the same type. - **`defaultAnswer(...)`** — replaces `RETURNS_DEFAULTS`; use `RETURNS_SMART_NULLS` while debugging, `CALLS_REAL_METHODS`, or a custom `Answer`. - **`lenient()`** — this mock's stubbings are exempt from unnecessary-stubbing failures; better than loosening the whole test. - **`extraInterfaces(Closeable.class)`** — the mock also implements those types, for legacy code that instanceof-checks or casts the collaborator. - **`serializable()`** — the mock survives Java serialization, needed when the code under test serializes its collaborator. - **`stubOnly()`** — invocations are not recorded, so no verification, but no memory growth for very chatty mocks. - **`verboseLogging()`** — prints every invocation, a quick debugging aid. Reach for settings sparingly; most mocks need none.
code
java · 10 linesClock start = mock(Clock.class, withSettings()
.name("startClock")
.defaultAnswer(Answers.RETURNS_SMART_NULLS));
OrderRepository repo = mock(OrderRepository.class, withSettings()
.name("orderRepo")
.lenient()
.extraInterfaces(Closeable.class));
((Closeable) repo).close(); // legacy code casts the collaboratorgo deeper
Know that mock() takes optional settings and be able to name two — a mock name and a different default answer.
Explain the main settings with the problem each solves, and that they are creation-time only and mirrored on @Mock attributes.
Talk about choosing the narrowest scope (per-mock lenient over class-wide), stubOnly as a memory tool, and treating extraInterfaces/serializable as signals about the production design.
Position settings as exceptions that should stay rare; a codebase where many mocks need tuning is telling you its seams are in the wrong place.
## Where settings live `Mockito.mock()` has an overload `mock(Class<T> type, MockSettings settings)`, and `Mockito.withSettings()` returns a fluent builder for that object. The same knobs are exposed as attributes on the annotation (`@Mock(name=…, answer=…, extraInterfaces=…, lenient=true, stubOnly=true, serializable=true)`), with the exception of options that need an object or have no attribute — a custom `Answer` instance, `verboseLogging()`, `invocationListeners(...)`, `mockMaker(...)`, `withoutAnnotations()` and `defaultAnswer` with a non-enum answer. ## The settings worth knowing **`name(String)`** — sets the mock's identity in output. Default `toString()` is `Mock for OrderRepository, hashCode: 123`, which is useless when a test holds `Clock start` and `Clock end`. Argument-mismatch reports and `verify` failures both print the name. Annotated mocks get this free from the field name, which is a good reason to prefer `@Mock` for shared collaborators. **`defaultAnswer(Answer)`** — controls unstubbed calls, replacing `RETURNS_DEFAULTS`. Built-ins in `org.mockito.Answers`: `RETURNS_DEFAULTS`, `RETURNS_SMART_NULLS` (placeholder that throws a locating `SmartNullPointerException`), `RETURNS_MOCKS`, `RETURNS_DEEP_STUBS`, `CALLS_REAL_METHODS`, `RETURNS_SELF` (for fluent builders — every method returning the mock's own type returns the mock, so you can mock a builder API). A custom `Answer` lets you do anything, including throwing on any unstubbed call to force explicitness. **`lenient()`** — with strict stubs (the default under Mockito's JUnit 5 integration), a stubbing that is never used fails the test. A mock created leniently is exempt for all its stubbings. This is the right granularity when one shared fixture mock is over-stubbed for some tests: it beats disabling strictness for the whole class, which would hide genuine dead stubs elsewhere. Mockito 4.6+ also offers `strictness(Strictness.LENIENT)` on settings, which reads more explicitly. **`extraInterfaces(Class…)`** — the generated mock implements the extra types too. The honest use case is legacy code that does `if (repo instanceof Closeable) ((Closeable) repo).close();` — you cannot express that with a single-type mock. It is explicitly documented as a last resort for code you cannot change; new code should not need it. **`serializable()`** — the mock and its recorded state are Java-serializable. Needed when the code under test puts the collaborator in an HTTP session, a distributed cache, or otherwise serializes it. There is a `serializable(SerializableMode)` variant for the across-classloaders case. **`stubOnly()`** — the mock does not record invocations. You lose all verification on that mock, and Mockito tells you so if you try. The payoff is memory: a mock invoked millions of times in a long-running or load-ish test otherwise accumulates every invocation and can exhaust the heap. **`verboseLogging()`** — attaches a listener that prints each invocation with its stubbed result and call site to stdout. A quick way to see what the code under test is really doing with a collaborator; remove before committing. `invocationListeners(...)` is the general form. **`useConstructor(...)` / `outerInstance(...)`** — for spies and for mocking non-static inner classes, i.e. cases where an instance genuinely must be constructed; rarely needed. **`mockMaker(String)`** and **`withoutAnnotations()`** — pick a specific mock maker for one mock, or strip annotations from the generated type (some frameworks scan annotations and misbehave on mocks). **`defaultAnswer` + `genericTypeToMock`** and **`strictness`** are the more recent additions; check the `MockSettings` javadoc for your version. ## How to use this in practice Most mocks need no settings at all — that is the point of good defaults. Treat a settings call as a signal: - `name` is pure ergonomics; use it freely. - `lenient` is a targeted escape hatch; each use should be explainable in one sentence. - `extraInterfaces` and `serializable` are almost always a report about the design of the code under test, not about the test. - `stubOnly` is a performance tool for a chatty mock; you are trading away verification, so only apply it where you never verify. - `RETURNS_DEEP_STUBS` deserves scepticism — see the separate discussion of deep stubs. ## Interview framing List three or four settings with the concrete problem each fixes, and say when you would *not* use them. Candidates who can only name `defaultAnswer` usually have not debugged a multi-mock failure message; mentioning `name()` and `lenient()` with a reason shows real usage.
- When would you use stubOnly() and what do you give up?Use it for a mock that is invoked a very large number of times — a logger, a metrics sink, a callback inside a tight loop — where recording every invocation grows the heap. You give up all verification and `InOrder` checks on that mock, because nothing is recorded; Mockito raises an error if you try to verify a stub-only mock. It is a memory optimisation, not a default.
- Why prefer creating one mock with lenient() over turning off strictness for the whole test class?Strict stubs catch genuinely dead stubbing, which is a real signal that a test no longer matches the code. Scoping leniency to the single over-stubbed fixture mock keeps that signal alive for every other mock in the class. Disabling strictness class-wide is a blunt instrument that hides future mistakes, so the per-mock setting is both narrower and self-documenting.
saying these in an interview costs you the question
- Thinking withSettings() options can be changed after the mock is created
- Using extraInterfaces() as a normal design tool rather than a legacy workaround
- Believing stubOnly() mocks can still be verified
- Turning off strictness class-wide when one mock needed lenient()
- Assuming every MockSettings option has an equivalent @Mock attribute