在Java中进行测试时,如何检查是否调用了接口的方法?

3
我想测试这个类,它使用匿名类调用接口方法。
public class ClassToTest 
{
    public void methodToTest()
    {
        InterefaceToMock interefaceToMockReference = new InterefaceToMock() {

            @Override
            public int methodToMock()
            {
                return 0;
            }
        };
        interefaceToMockReference.methodToMock();
    }
}

这是界面。

public interface InterefaceToMock 
{
    public int methodToMock();
}

我使用这种方法来检查是否调用了methodToMock
import static org.junit.Assert.*;

import org.junit.Test;

import mockit.FullVerificationsInOrder;
import mockit.Mocked;
import mockit.NonStrictExpectations;
public class TestAClass 
{
    @Mocked InterefaceToMock interefaceToMockReferenceMocked;
    @Test
    public void test1()
    {
        new NonStrictExpectations()
        {
            {
                interefaceToMockReferenceMocked.methodToMock();times=1;
            }
        };
        (new ClassToTest()).methodToTest();
        new FullVerificationsInOrder(interefaceToMockReferenceMocked)
        {
        };
        assertTrue(true);
    }
}

但测试用例失败了。 有人能帮忙吗。


1
我不明白这里发生了什么。如果没有将实例的引用传递进来,ClassToTest.methodToTest()如何调用InterefaceToMock.methodToMock() - Boris the Spider
它是如何失败的?AssertTrue(true)永远不会失败。混乱、令人困惑的代码。糟糕的命名。 - duffymo
@BoristheSpider 这被称为使用匿名类对象。 - वरुण
@duffymo 验证失败。 - वरुण
1
在这种情况下,期望记录块或期望验证块应该被删除一个,因为你只需要一个。 - Rogério
2个回答

2

一般情况下,如果您有一个 class 并且想要检查该 classMock 上是否调用了某个方法,则使用 Mockito.verify

例如:

public class AppTest {
    @Test
    public void testMe() {
        final ITest iTest = Mockito.mock(ITest.class);
        final CUT cut = new CUT(iTest);
        cut.doStuff();
        Mockito.verify(iTest).someStuff();
    }

    interface ITest {
        void someStuff();
    }

    class CUT {
        private final ITest iTest;

        CUT(ITest iTest) {
            this.iTest = iTest;
        }

        public void doStuff() {
            iTest.someStuff();
        }
    }
}

这里的测试是检查是否从 CUT.doStuff() 调用了 ITest.someStuff()

您的示例无法理解...


感谢您的支持。正如您所见,我无法将模拟实例传递给我正在测试的类。就像这样 "final CUT cut = new CUT(iTest);" 请根据给定的示例提供答案。我必须使用 JMockit,不能使用其他任何模拟框架。这是一种限制。如果您在示例中无法理解任何内容,请随时询问哪些方面不清楚。 - वरुण

2

你的原始测试基本正确。它将模拟字段声明为@Mocked,这仅给你一个实现接口的单个模拟实例,并且这不是被测试代码使用的实例。然而,JMockit API有另一个模拟注解,它将模拟扩展到给定基类型的所有实现类,并默认影响所有该类的实例。因此,测试应更改如下:

public class TestAClass 
{
    @Capturing InterfaceToMock anyImplementingInstance;

    @Test
    public void test1()
    {
        new ClassToTest().methodToTest();

        new Verifications() {{
            anyImplementingInstance.methodToMock();
        }};
    }
}

谢谢。你的答案有效。我已经按照你在评论中建议的使用期望验证块或期望记录块的方法进行了操作。code import org.junit.Test; import mockit.Capturing; import mockit.NonStrictExpectations;public class TestAClass { @Capturing InterfaceToMock anyImplementingInstance;@Test public void test1() { new NonStrictExpectations() { { anyImplementingInstance.methodToMock();times=1; } }; new ClassToTest().methodToTest(); }} code - वरुण
这种方法也可以工作。code new NonStrictExpectations() { @Capturing InterfaceToMock anyImplementingInstance; { anyImplementingInstance.methodToMock();times=1; } };code 我可以使用这种方法吗?因为我不想在其他测试方法中对InterfaceToMock进行模拟。 - वरुण
Maven不支持在测试用例中传递参数。 - वरुण
它可以工作。但是当我们使用maven install时,maven会显示错误,指出测试方法中不应该有参数。 - वरुण
在这种情况下,您应该将jmockit依赖项在pom.xml文件中放在junit之前,或者在每个测试类上注释@RunWith(JMockit.class),以使类路径顺序无关紧要。 - Rogério
显示剩余2条评论

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