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

Mockito使用doReturn仍触发Stub方法问题及集成测试方案咨询

Hey there, let's break down why your stubbed method is firing early and how to fix this common testing pitfall!

Possible Reasons for Early Method Execution

1. Incorrect Stubbing Syntax (The #1 Culprit)

If you wrote your doReturn stub like this, you’re accidentally triggering the real method call while setting up the stub:

// ❌ Wrong: Evaluates the method call inside `when()` immediately
Mockito.doReturn(updatedProject)
       .when(projectService.synchronizeWithDamAndSave(any(Project.class)));

The expression inside when() gets executed before Mockito can intercept it, which runs the real synchronizeWithDamAndSave logic before your API request even starts.

2. Using a Real Instance Instead of a Spy/Mock

If your ProjectService is a raw, real Spring Bean (not wrapped with @SpyBean or @MockBean), Mockito can’t intercept its methods. Your doReturn setup will be ignored, and the real method will run whenever it’s called.

3. Early Triggering in Initialization Logic

Check your @BeforeEach/@BeforeAll methods or test class constructor—you might be accidentally calling code that invokes synchronizeWithDamAndSave before your stub is fully set up.


Fixes to Resolve the Issue

1. Correct the Stubbing Syntax

Rewrite your doReturn stub to avoid executing the real method during setup. The key is to separate the mock/spy reference from the method call:

// ✅ Correct: No real method call happens here
Mockito.doReturn(mockUpdatedProject)
       .when(projectService)
       .synchronizeWithDamAndSave(any(Project.class));

This tells Mockito to intercept calls to synchronizeWithDamAndSave on projectService without running the real method first.

2. Use @SpyBean or @MockBean for Spring Integration Tests

In Spring Boot integration tests:

  • Use @SpyBean if you want to keep most of the real ProjectService logic but stub just this one method.
  • Use @MockBean if you want to replace the entire ProjectService with a mock (good if you don’t need other methods to run real logic).

Example test setup:

@SpringBootTest
@AutoConfigureMockMvc
public class ProjectControllerUpdateTest {

    @Autowired
    private MockMvc mockMvc;

    @SpyBean // Wraps the real bean to allow selective stubbing
    private ProjectService projectService;

    @Test
    void testPutUpdateProject() throws Exception {
        // 1. Set up the stub FIRST
        Project stubbedResult = new Project();
        stubbedResult.setId(1L);
        stubbedResult.setName("Updated Test Project");

        doReturn(stubbedResult)
          .when(projectService)
          .synchronizeWithDamAndSave(any(Project.class));

        // 2. Send the PUT request
        mockMvc.perform(put("/projects/1")
                .contentType(MediaType.APPLICATION_JSON)
                .content("{\"name\":\"Updated Test Project\"}"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.name").value("Updated Test Project"));

        // Optional: Verify the method was called as expected
        verify(projectService, times(1))
          .synchronizeWithDamAndSave(any(Project.class));
    }
}

3. Adjust Initialization Order

Make sure all stubbing logic runs before any code that could trigger synchronizeWithDamAndSave. Move stub setup to the start of your test method, and double-check that @BeforeEach methods aren’t invoking related service logic prematurely.

4. Use Precise Argument Matchers

If your stub isn’t matching the actual method call (e.g., because you’re using a specific object instead of a matcher), Mockito will fall back to the real method. Use matchers like any(), eq(), or argThat() to ensure your stub catches the right calls:

// Stub only calls with a project ID of 1
doReturn(stubbedResult)
  .when(projectService)
  .synchronizeWithDamAndSave(argThat(p -> p.getId().equals(1L)));

内容的提问来源于stack exchange,提问作者Oncioiu Costin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 16:17:39