You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

doReturn-when与when-thenReturn在Mock/Spy对象中的行为差异

Mockito Spy: Avoiding Real Nested Method Calls with doReturn-when vs when-thenReturn

Great question—this is a super common gotcha when working with Mockito Spies, so let’s break it down clearly.

Which One Works for Skipping Real Nested Method Calls?

Short answer: Use doReturn(...).when(spyObject).nestedMethod() if you want to avoid triggering the real execution of nested methods in your Spy.

Here’s the critical difference between the two:

  • when(spyObject.nestedMethod()).thenReturn(...) operates by first calling the real version of nestedMethod() on the Spy, then replacing its return value with your mock. That means any side effects, calls to other methods, or logic inside the real nested method will still run before the mock kicks in.
  • doReturn(...).when(spyObject).nestedMethod() skips the real method entirely. It directly tells Mockito to return your specified value whenever nestedMethod() is called, without executing a single line of the real code inside it.

Example to Make This Concrete

Let’s use a simple class where a main method calls a nested method we want to mock:

public class OrderService {
    public String processOrder() {
        // We want to mock this nested method call
        String inventoryStatus = checkInventory();
        return "Order processed: " + inventoryStatus;
    }

    public String checkInventory() {
        // Real code we don't want to run in tests (e.g., database calls)
        System.out.println("Real inventory check ran!");
        return "In Stock";
    }
}

Using when-thenReturn (Triggers Real Method)

@Test
void testWithWhenThenReturn() {
    OrderService spy = Mockito.spy(new OrderService());
    when(spy.checkInventory()).thenReturn("Mocked: In Stock");

    String result = spy.processOrder();
    // You'll see "Real inventory check ran!" printed to the console
    assertEquals("Order processed: Mocked: In Stock", result);
}

Using doReturn-when (Skips Real Method)

@Test
void testWithDoReturnWhen() {
    OrderService spy = Mockito.spy(new OrderService());
    doReturn("Mocked: In Stock").when(spy).checkInventory();

    String result = spy.processOrder();
    // No "Real inventory check ran!" output—real method never executed
    assertEquals("Order processed: Mocked: In Stock", result);
}

Other Ways to Avoid Real Method Calls in Spies

Besides doReturn, you can use other doXxx methods for different scenarios:

  • doThrow(new InventoryUnavailableException()).when(spy).checkInventory(): Make the nested method throw an exception without running real code.
  • doAnswer(invocation -> "Custom Stock Status").when(spy).checkInventory(): Replace the real method with custom logic, skipping the real execution entirely.

If you find yourself needing to mock most methods of an object, consider using a full @Mock instead of a @Spy—Spies are designed for partial mocking (keeping most methods real while mocking a few), while Mocks are for full isolation. But if you must use a Spy (e.g., testing a specific method while mocking its internal dependencies), doReturn-when is your go-to tool.

内容的提问来源于stack exchange,提问作者Lahiru Pathirana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:01:47