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

如何正确测试保存对象并返回ID的Service方法?

问题分析

你当前测试失败的核心原因是:Service方法内部是自行创建NewObject实例的,你mock的newObjectmock并没有被Service使用。虽然你让repository.save()返回了这个mock对象,但Service里始终用的是它一开始创建的那个NewObject实例,而这个实例的id并没有被设置,所以返回null。

正确测试方案

针对这种场景,有两种常用的解决方式:

方式一:使用Mockito Answer 修改Service创建的对象ID

通过Answer接口,在repository.save()被调用时,直接修改传入的NewObject实例的id,这样Service里的对象就能拿到正确的id值:

@Test
void addNotification() {
    // 当repository.save被调用时,修改传入的NewObject的id为1L
    when(repository.save(any(NewObject.class))).thenAnswer(invocation -> {
        NewObject actualObject = invocation.getArgument(0);
        actualObject.setId(1L); // 假设NewObject有setId方法
        return actualObject;
    });

    // 调用Service方法
    long resultId = service.addNotification(new ObjectWithInformation());

    // 验证结果
    assertEquals(1L, resultId);
    verify(repository).save(any(NewObject.class));
    verify(repository).flush();
}

方式二:Spy真实的NewObject实例(如果NewObject是简单POJO)

如果NewObject是普通的POJO类,可以用spy来包装真实实例,让getId()返回指定值,同时确保Service里的对象是这个spy实例:

@Test
void addNotification() {
    // 创建真实NewObject的spy实例
    NewObject spyObject = spy(new NewObject());
    doReturn(1L).when(spyObject).getId();

    // 需确保Service创建的是这个spyObject,可通过调整依赖注入实现,比如构造注入
    when(repository.save(eq(spyObject))).thenReturn(spyObject);

    long resultId = service.addNotification(new ObjectWithInformation());

    assertEquals(1L, resultId);
}
关键注意点
  • 不要试图mock Service内部new出来的对象,除非使用PowerMock(不推荐,会增加测试复杂度)。
  • 优先使用Answer来修改传入的真实对象,这种方式更贴近真实业务逻辑,测试也更可靠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 18:01:20