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

Junit5 Mockito-inline如何对同一类构造函数两次mock设置不同行为

解决方法

你可以通过计数器标记Source的构造顺序,分别给不同次构造的实例设置不同的mock行为。MockedConstruction的初始化回调会严格按照对象实例化的先后顺序触发,刚好符合你的场景:第一个构造的Source是Account数据源,第二个是Hardware数据源。

修改后的测试代码如下:

public class ServiceTest {

  @Test
  public void testScenario() {
    List<Account> accountList = new ArrayList<>();
    // 可提前向accountList添加测试用Account数据
    List<Hardware> hardwareList = new ArrayList<>();
    // 可提前向hardwareList添加测试用Hardware数据

    // 原子计数器标记构造次数,适配JUnit多线程执行场景
    AtomicInteger constructCount = new AtomicInteger(0);

    try (MockedConstruction<Source> construction = Mockito.mockConstruction(Source.class, (mock, context) -> {
      // 统一设置hasNext返回逻辑:首次调用返回true,第二次返回false,适配while循环
      Mockito.when(mock.hasNext()).thenReturn(true, false);
      int count = constructCount.getAndIncrement();
      if (count == 0) {
        // 第一次构造为Account数据源,返回accountList
        Mockito.when(mock.getData()).thenReturn(accountList);
      } else if (count == 1) {
        // 第二次构造为Hardware数据源,返回hardwareList
        Mockito.when(mock.getData()).thenReturn(hardwareList);
      }
    })) {
      new Service().solve();
      // 验证Source实例构造次数符合预期
      Assertions.assertEquals(2, construction.constructed().size());
      // 此处可添加业务逻辑相关断言
    }
  }
}

补充说明

  1. 你之前尝试按泛型区分Source<Account>和Source<Hardware>的mock不生效,是因为Java泛型是编译期特性,运行期会发生类型擦除,两个带不同泛型的Source属于同一个类,Mockito无法通过泛型参数区分不同实例。
  2. 如果实际业务中两个Source初始化传入的url参数不同,也可以通过context.arguments().get(0)获取构造时传入的url值来区分实例,比依赖构造顺序的实现更稳妥。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 23:57:02