JMockit - Expectations vs MockUp<T>:为什么一个有效而另一个无效?

8
我正在努力学习JMockit的各个方面。这里是另一个我不理解的JMockit怪异之处的例子。使用NonStrictExpectations运行测试完全正常。然而,使用MockUp运行测试不行。我不确定原因。有任何想法吗?我正在运行JMockit 1.5。
要测试的方法:
private List<Foo> getFooList(List<FooStatement> fooStatements){
    List<Foo> FooList = new ArrayList<Foo>();

    for(FooStatement at: fooStatements){
        List<Foo> aList = at.getFoos();
        FooList.addAll(aList);
    }

    return FooList;
}

成功期望测试
@Test
public void getFooListWithExpectationsTest(
        @Mocked final FooStatement mockFooStatement,
        @Mocked final Foo mockFoo
){

    List<FooStatement> fooStatementList = new ArrayList<>(Arrays.asList(
            mockFooStatement,
            mockFooStatement
    ));

    new NonStrictExpectations(){{
        mockFooStatement.getFoos();
        result = new ArrayList<Foo>(Arrays.asList(mockFoo));
    }};

    List<Foo> fooList = Deencapsulation.invoke(handler, "getFooList", fooStatementList);
    Assert.assertTrue(fooList.size() == 2);
}

使用MockUp时出现断言错误(0 != 2)

@Test
public void getFooListWithMockUpTest(
        @Mocked final FooStatement mockFooStatement,
        @Mocked final Foo mockFoo
){

    new MockUp<FooStatement>(){
        @Mock
        public List<Foo> getFoos(){
            return new ArrayList<Foo>(Arrays.asList(mockFoo));
        }
    };

    List<FooStatement> fooStatementList = new ArrayList<>(Arrays.asList(
            mockFooStatement,
            mockFooStatement
    ));

    List<Foo> fooList = Deencapsulation.invoke(handler, "getFooList", fooStatementList);
    Assert.assertTrue(fooList.size() == 2);
}
2个回答

4
您正在错误使用 MockUp<?>。使用 MockUp<T? 将告诉 JMockit 重新定义加载到 JVM 中的类,以便替换 FooStatement 的实际类初始化为在 MockUp<FooStatement 中定义的类。

因此,MockUp<FooStatement> 将自动替换对 new FooStatement() 的调用。

尝试这样做:

@Test
public void getFooListWithMockUpTest(@Mocked final Foo mockFoo){

    new MockUp<FooStatement>(){
        @Mock
        public List<Foo> getFoos(){
            return new ArrayList<Foo>(Arrays.asList(mockFoo));
        }
    };

    List<FooStatement> fooStatementList = new ArrayList<>(Arrays.asList(
            new FooStatement(),
            new FooStatement()
    ));

    List<Foo> fooList = Deencapsulation.invoke(handler, "getFooList",     fooStatementList);
    Assert.assertTrue(fooList.size() == 2);
}

啊,这很有道理。但是FooStatement是一个接口,这意味着每次我实例化一个对象时,都必须实现它的所有方法。看起来在这种情况下使用new MockUp<T>并不是最好的选择。感谢您的帮助。 - Will Lovett
有没有办法只使用MockUp<T>来模拟方法调用?如果不是的话,我猜这就是Expectations的作用了。 - Will Lovett
1
通常情况下,您不会在同一个测试中同时使用Expectations API和Mockups API。它们是针对不同需求的不同API。 "Expectations"用于面向行为的单元测试,其中您关注于被测试类对其协作者的方法调用,而"Mockups"用于状态导向测试中使用的虚假实现。 - Rogério
MockUp已被弃用,请使用Expectations。请查看官方GitHub页面jmockit.github.io/changes.html。 - Vadiraj S J

-3

MockUp已被弃用,使用Expectations


你能提供你的源代码吗? - Spik330
请查看:https://jmockit.github.io/changes.html 版本1.39(2018年3月25日):已删除MockUp#getMockInstance()方法,该方法在版本1.37中已弃用。官方文档明确表示不要使用MockUp。 - Vadiraj S J
4
版本1.37(2017年11月26日):已弃用MockUp类中的getMockInstance()方法。通常,此方法仅用于获取模拟接口的实例。对于模拟类而言,它没有实际用途。建议不要使用模拟来创建接口类型的模拟,而是创建一个最小的实现类或使用现有的实现。 - Spik330

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接