skip to content

Stubbing Exceptions (thenThrow)

thenThrow and doThrow make a mock fail on demand, subject to the rule that checked exceptions must be declared by the method. Interviewers use exception stubbing to check that you actually test the unhappy paths.

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

questions

4

How do you make a Mockito mock throw an exception when a method is called, and what are the two ways to pass the exception?

level: juniorimportance: must knowfreq 70%

answer

  1. when(...).thenThrow(instance OR class)
  2. class form uses no-arg constructor
  3. instance form = custom message/cause
  4. checked must match the throws clause
  5. chain throws for consecutive calls

basics

~10 s

Use when(mock.method()).thenThrow(...). You can pass either an exception instance (new IllegalStateException("x")) or an exception class (IllegalStateException.class), which Mockito instantiates for you.

solid answer

~40 s

To stub a method that returns a value, the common form is when(mock.foo()).thenThrow(...). You may pass an exception instance, e.g. thenThrow(new IllegalStateException("boom")), or an exception class, e.g. thenThrow(IllegalStateException.class), in which case Mockito creates an instance with its no-arg constructor. Passing the class is concise when you do not care about the message; passing an instance lets you assert on the message or wrapped cause later. You can list several exceptions to throw them on successive calls. When you need a real custom message or a chained cause, build the instance yourself. For checked exceptions there is a constraint: the exception must be declared by the stubbed method, otherwise Mockito rejects it at stub time.

go deeper

for a junior

Knows the when(...).thenThrow(...) form and that you can pass an exception object or class.

for a middle

Explains the class-vs-instance trade-off and that the class form uses the no-arg constructor.

for a senior

Articulates the checked-exception constraint, consecutive-call chaining, and when each form is appropriate.

for a principal

Frames exception stubbing within a failure-path testing strategy and guides the team on readable, intention-revealing stubs vs. over-mocking.

## What is a mock and what is stubbing? In unit testing you often replace a real collaborator (a dependency of the class under test) with a fake object so the test is fast and isolated. **Mockito** is a popular Java mocking library. A **mock** is such a fake: by default its methods do nothing and return harmless defaults (`null`, `0`, `false`, empty collections). **Stubbing** means telling the mock how to behave for a specific call — "when this method is called, do that." ## Why make a mock throw? Real dependencies fail: a database is down, a network call times out, a file is missing. To test that your code handles those failures (retries, logs, wraps the error, returns a fallback), you need the dependency to *fail on command*. Stubbing an exception is how you simulate that failure deterministically. ## The two stubbing entry points Mockito has two grammars for stubbing: 1. **`when(...).thenThrow(...)`** — the readable, default form. It works for methods that **return a value** (non-`void`). 2. **`doThrow(...).when(mock).method()`** — needed for **`void`** methods (covered in a sibling question) and a few other cases. ## Passing an exception class vs. an instance `thenThrow` (and `doThrow`) accept either: - **A `Throwable` instance:** `thenThrow(new IllegalStateException("db down"))`. You control the message and can attach a *cause* (the original exception). Use this when the test later asserts on the message or cause. - **A `Class<? extends Throwable>`:** `thenThrow(IllegalStateException.class)`. Mockito instantiates it for you using the **no-argument constructor**. This is concise when the message does not matter. Caveat: if the exception type has *no* accessible no-arg constructor, Mockito cannot create it and will fail — pass an instance instead. ```java // instance form: full control of message/cause when(repo.find(1L)).thenThrow(new IllegalStateException("db down")); // class form: Mockito builds it with the no-arg constructor when(repo.find(1L)).thenThrow(IllegalStateException.class); ``` ## Multiple exceptions / consecutive calls You can chain values so each successive call behaves differently: ```java when(repo.find(1L)) .thenThrow(new TimeoutException()) // 1st call .thenReturn(user); // 2nd call onward ``` This is ideal for testing retry logic. ## The checked-exception constraint Java distinguishes **checked** exceptions (subclasses of `Exception` but not `RuntimeException`, which the compiler forces you to declare/handle) from **unchecked** ones (`RuntimeException` / `Error`, which need no declaration). Mockito enforces a rule mirroring the compiler: a stubbed method may only be told to throw a **checked** exception that its signature actually declares (`throws ...`). Throwing a checked exception the method does not declare would be impossible in real code, so Mockito rejects it at stub time with `MockitoException: Checked exception is invalid for this method!`. **Unchecked** exceptions (`RuntimeException`, `Error`, and their subclasses) can always be stubbed on any method. ## Summary - Returning methods: `when(mock.m()).thenThrow(...)`. - Pass an instance for a custom message/cause, or a class for brevity (needs a no-arg constructor). - Checked exceptions must be in the method's `throws` clause; unchecked ones are always allowed.

  • When would you prefer passing an instance over a class?
    When the test needs a specific message or a wrapped cause to assert on, or when the exception type has no no-arg constructor for Mockito to call.
  • What happens if you pass IllegalStateException.class and it lacks a no-arg constructor?
    Mockito can't instantiate it and the stubbing fails; pass a pre-built instance instead.

saying these in an interview costs you the question

  • Thinking you can stub any checked exception regardless of the method signature
  • Believing the class form lets you set a message (it uses the no-arg constructor)
  • Using when().thenThrow() on a void method (it won't compile)

context

open as a page

Why can't you use when(...).thenThrow(...) for a void method, and how do you stub a void method to throw?

level: middleimportance: must knowfreq 65%

basics

~10 s

A void method returns nothing, so you can't pass its call into when(...). Use the do-form instead: doThrow(new RuntimeException()).when(mock).doStuff();

open as a page

What is Mockito's constraint on stubbing checked exceptions, and why does it exist?

level: seniorimportance: should knowfreq 50%

basics

~10 s

You can only stub a checked exception that the method actually declares with throws. Unchecked exceptions (RuntimeException/Error) are always allowed. Otherwise Mockito fails with "Checked exception is invalid for this method!".

open as a page

How do you make a mock throw on the first call but succeed on retries, and when would you reach for thenAnswer/doAnswer instead of thenThrow?

level: seniorimportance: nice to knowfreq 35%

basics

~10 s

Chain stubs: when(mock.call()).thenThrow(new TimeoutException()).thenReturn(value). The first call throws, later calls return. Use thenAnswer/doAnswer when whether (or what) to throw depends on the actual arguments.

open as a page