skip to content

Mockito Mock Creation

Mockito.mock or @Mock gives you a stand-in whose methods return null, zero, false or empty by default, letting you isolate the unit under test. Interviewers often start here and move to what you should mock versus use for real.

part ofJavaoverview, primer and where to startread it →
on this pageshow

questions

5

What does a freshly created, unstubbed Mockito mock return when its methods are called, for various return types?

level: juniorimportance: must knowfreq 75%

answer

  1. objects -> null
  2. numbers -> 0, boolean -> false
  3. collections -> EMPTY, not null
  4. Optional -> Optional.empty()
  5. default Answer = RETURNS_DEFAULTS

basics

~20 s

An unstubbed mock returns safe empty defaults: null for objects, 0 for numbers, false for booleans, and empty collections (an empty list/set/map, not null). So calling a method you didn't stub won't throw on its own.

solid answer

~40 s

A fresh mock has no programmed behaviour, but every method must still return something, so Mockito supplies type-appropriate defaults via its default answer (RETURNS_DEFAULTS). Object references return null. Numeric primitives (int, long, double, etc.) return 0; boolean returns false; char returns the null character. Crucially, collection and container return types return empty instances rather than null — empty List, Set, Map, Stream, and Optional.empty() — so iterating the result of an unstubbed call is safe and won't NPE. This is why you only stub the calls your assertion actually depends on; everything else returns a harmless default. void methods simply do nothing. You can change this policy globally by creating the mock with a different Answer, e.g. mock(Foo.class, RETURNS_DEEP_STUBS) or RETURNS_SMART_NULLS, but the empty-default behaviour is the sensible out-of-the-box contract.

go deeper

for a junior

Knows the basic defaults: null for objects, 0/false for primitives, empty collections.

for a middle

Can name Optional.empty() and explain why empty-collection defaults prevent NPEs and reduce needed stubbing.

for a senior

Knows the default is a pluggable Answer (RETURNS_DEFAULTS) and can name alternatives like RETURNS_SMART_NULLS/RETURNS_DEEP_STUBS and their trade-offs.

for a principal

Reasons about default-answer choices as a team convention, the risks of RETURNS_DEEP_STUBS hiding Law-of-Demeter violations, and how defaults interact with strict-stubbing test hygiene.

## Why defaults exist at all When you create a mock with `mock(SomeType.class)`, none of its methods have been **stubbed** (programmed). But Java still requires every non-`void` method to return a value of the declared type. Mockito therefore consults a **default Answer** for any call you have not explicitly scripted. An `Answer<T>` is Mockito's strategy interface for 'what should this unstubbed call return?'. The out-of-the-box default is `RETURNS_DEFAULTS`, backed internally by the `ReturnsEmptyValues` answer. ## The exact defaults | Declared return type | Default returned | |---|---| | Any object reference (`String`, `Order`, custom types) | `null` | | `boolean` / `Boolean` | `false` | | `int`, `long`, `short`, `byte`, `double`, `float` | `0` (zero of that type) | | `char` | `'\u0000'` (the null character) | | `List`, `Collection`, `Iterable` | empty `List` | | `Set` | empty `Set` | | `Map` | empty `Map` | | `Stream` | empty `Stream` | | `Optional` | `Optional.empty()` | | array | empty array (length 0) | | `void` | nothing happens (no exception) | The key design choice is the **collection/container row**: Mockito returns an *empty* collection, never `null`. This matters because real code very often does `for (X x : collaborator.getThings())` or `collaborator.find().stream()...`. If the default were `null`, every unstubbed call feeding such a loop would throw `NullPointerException`, forcing you to stub calls you do not care about. By returning empty containers, Mockito lets you stub **only** what the specific test asserts on. ## Practical consequence ```java OrderRepository repo = mock(OrderRepository.class); repo.findById(99L); // returns null (Optional<Order>? -> actually Optional.empty()) repo.findAll(); // returns an empty List, NOT null repo.count(); // returns 0L repo.exists(5L); // returns false ``` So a test can construct the SUT, call it, and only the *relevant* collaborator methods need `when(...).thenReturn(...)`. Unstubbed calls silently fall through to defaults. ## Note on Optional/null and `findById` If a method's declared return type is `Optional<Order>`, the default is `Optional.empty()` (a container), not `null`. If the method returns the bare object `Order`, the default is `null`. The rule is about the *declared static type*, not the value you expect. ## Overriding the default answer You can pass a different global `Answer` at creation: - `RETURNS_SMART_NULLS` — instead of a plain `null`, returns a placeholder that throws a more helpful `SmartNullPointerException` (telling you which unstubbed call produced the null) if you later dereference it. Useful while debugging NPEs. - `RETURNS_DEEP_STUBS` — auto-mocks the return value too, so `a.getB().getC()` works without stubbing each level (use sparingly; it hides design issues). - `RETURNS_MOCKS` — returns mocks for mockable types instead of null. - A custom `Answer` lambda for bespoke logic. ```java Foo foo = mock(Foo.class, RETURNS_SMART_NULLS); ``` But for everyday tests, the empty-value default is exactly what you want, and understanding it explains why so many Mockito tests stub surprisingly few methods.

  • Why does Mockito return empty collections instead of null by default?
    So that code which iterates or streams the result of an unstubbed call doesn't NPE, letting you stub only the calls your assertion depends on rather than every method that happens to be invoked.
  • How would you make a mock surface unstubbed-null usages more loudly?
    Create it with RETURNS_SMART_NULLS, which returns a placeholder that throws a descriptive SmartNullPointerException when dereferenced, pointing at the unstubbed call.

saying these in an interview costs you the question

  • Claiming an unstubbed collection method returns null (it returns an empty collection)
  • Saying an unstubbed call throws an exception by default — it does not (with the standard default answer)
  • Thinking you must stub every method to avoid crashes
  • Confusing the default for Optional (empty) with the default for a bare object (null)

context

open as a page

What is a mock object in Mockito, how do you create one, and why would you use it in a unit test?

level: juniorimportance: must knowfreq 85%

basics

~20 s

A mock is a fake stand-in for a real object that you create with Mockito.mock(SomeClass.class). You use it to replace a real collaborator so your test exercises only the one class you care about, without its dependencies doing real work.

open as a page

How does the @Mock annotation relate to Mockito.mock(Class), and what is required to make @Mock fields actually become mocks?

level: middleimportance: must knowfreq 70%

basics

~10 s

@Mock is shorthand for Mockito.mock(SomeClass.class) on a field. But the annotation does nothing by itself — you must initialize it, either with @ExtendWith(MockitoExtension.class) (JUnit 5) or MockitoAnnotations.openMocks(this) in a setup method.

open as a page

How does Mockito.mock create a mock at the bytecode level, and what limits exist for final classes, final methods, and static methods?

level: seniorimportance: should knowfreq 40%

basics

~20 s

Mockito generates the mock at runtime by subclassing the type (using ByteBuddy) and overriding its methods. The default subclass approach can't override final classes/methods or static methods. The newer inline mock maker (default in Mockito 5) can mock final and static via mockStatic.

open as a page

When should you mock a collaborator versus using the real object (or a fake), and what are the risks of over-mocking?

level: seniorimportance: should knowfreq 55%

basics

~20 s

Mock collaborators that are slow, external, non-deterministic, or hard to set up (databases, HTTP, clocks). Use the real object for simple value or pure-logic dependencies. Over-mocking couples tests to implementation details and can hide real integration bugs.

open as a page