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()); // 此处可添加业务逻辑相关断言 } } }
补充说明
- 你之前尝试按泛型区分
Source<Account>和Source<Hardware>的mock不生效,是因为Java泛型是编译期特性,运行期会发生类型擦除,两个带不同泛型的Source属于同一个类,Mockito无法通过泛型参数区分不同实例。 - 如果实际业务中两个
Source初始化传入的url参数不同,也可以通过context.arguments().get(0)获取构造时传入的url值来区分实例,比依赖构造顺序的实现更稳妥。
内容的提问来源于stack exchange,提问作者abdelgany mahmoud
相关产品推荐
相关产品推荐

