skip to content

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