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

Spring Boot3+MongoDB的JUnit测试中Strict stubbing参数不匹配问题

解决Mockito Strict Stubbing参数不匹配问题

问题场景

基于Spring Boot 3.3.3和MongoDB编写JUnit测试时,运行TestNoteService的createNoteTest方法抛出org.mockito.exceptions.misusing.PotentialStubbingProblem异常,提示Strict stubbing参数不匹配:save方法实际调用传入的Note对象id为5f3623af,但存根配置使用的Note对象id为sghgak17,二者不一致。

相关代码如下:

Note实体类

@Document(collection = "Notes")
public class Note {

    @Id
    private String id; //(auto-generated UUID or MongoDB ObjectId)
    private String title;
    private String content;
    private LocalDateTime createdAt;
    private LocalDateTime updatedAt;
    // 省略getter、setter、builder等方法
}

TestNoteService测试类

@ExtendWith(MockitoExtension.class)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class TestNoteService {

    @Mock
    private NotesRepository notesRepository;

    @InjectMocks
    private NoteService noteService;

    private Note note;

    @BeforeEach
    public void setup() {
        note = Note.builder()
                .id("sghgak17")
                .title("Title")
                .content("Testing Content.")
                .createdAt(LocalDateTime.now())
                .updatedAt(LocalDateTime.now())
                .build();
    }

    @Test
    @Order(1)
    public void createNoteTest() {
        given(notesRepository.save(note)).willReturn(note);
        Note savedNote = noteService.createNote(note); 
        System.out.println(savedNote);
    }
}

解决方案

1. 使用任意对象匹配器(最常用)

将存根中的具体Note对象替换为any(Note.class),Mockito会匹配任意传入的Note实例,不再严格校验对象的所有属性:

@Test
@Order(1)
public void createNoteTest() {
    // 匹配任意Note对象
    given(notesRepository.save(any(Note.class))).willReturn(note);
    Note savedNote = noteService.createNote(note); 
    assertThat(savedNote).isNotNull();
}

2. 自定义参数匹配逻辑(精准匹配)

如果需要校验除id外的其他属性是否匹配,可以使用argThat自定义匹配规则,忽略自动生成的id字段:

@Test
@Order(1)
public void createNoteTest() {
    given(notesRepository.save(argThat(n -> 
        n.getTitle().equals(note.getTitle()) && 
        n.getContent().equals(note.getContent()) &&
        n.getCreatedAt() != null &&
        n.getUpdatedAt() != null
    ))).willReturn(note);
    
    Note savedNote = noteService.createNote(note); 
    assertThat(savedNote).isNotNull();
}

3. 修正测试数据与业务逻辑匹配

检查NoteService的createNote方法实现,大概率是该方法在保存前自动生成了新的id(比如UUID或MongoDB自动生成的ObjectId),此时测试代码不应手动设置id:

  • 修改setup方法,移除手动设置id的代码:
@BeforeEach
public void setup() {
    note = Note.builder()
            .title("Title")
            .content("Testing Content.")
            .createdAt(LocalDateTime.now())
            .updatedAt(LocalDateTime.now())
            .build(); // 不再手动设置id
}
  • 存根时使用任意对象匹配器或自定义匹配逻辑即可。

4. 临时关闭Strict Stubbing(不推荐)

如果只是临时绕过该校验,可以在测试类上添加@MockitoSettings(strictness = Strictness.LENIENT)关闭Strict Stubbing模式,但这会隐藏潜在的参数不匹配问题,仅作为应急方案:

@ExtendWith(MockitoExtension.class)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@MockitoSettings(strictness = Strictness.LENIENT) // 关闭Strict Stubbing
public class TestNoteService {
    // ... 测试代码不变
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 10:12:47