【问题标题】:EasyMock says unexpected invocation when the invocation is expectedEasyMock 在预期调用时说意外调用
【发布时间】:2014-12-24 13:34:47
【问题描述】:

我在使用 EasyMock 时遇到了一些奇怪的行为。我已经设定了一些期望,但是当我运行我的测试时,EasyMock 失败了,因为我的期望按照指定的方式执行。下面是一个失败的例子:

Unexpected method call MyClass.myMethod(en, EasyMock for interface com.google.common.collect.Multimap, EasyMock for interface java.util.concurrent.BlockingQueue, EasyMock for interface java.util.concurrent.BlockingQueue):
  MyClass.myMethod(en, EasyMock for interface com.google.common.collect.Multimap, EasyMock for interface java.util.concurrent.BlockingQueue, EasyMock for interface java.util.concurrent.BlockingQueue): expected: 100, actual: 0

测试看起来像这样:

Multimap<String, String> multimap = createMock(Multimap.class);
BlockingQueue<MyType> myTypeQueue = createMock(BlockingQueue.class);
BlockingQueue<MyOtherType> myOtherTypeQueue = createMock(BlockingQueue.class);
MyClass myClass = createMock(MyClass.class);

QueueFactory queueFactory = createMock(QueueFactory.class);
expect(queueFactory.<MyType>getQueue(100)).andReturn(myTypeQueue).times(2);
expect(queueFactory.<MyOtherType>getQueue(100)).andReturn(myOtherTypeQueue).times(2);

expect(myClass.myMethod("en", multimap, myTypeQueue, myOtherTypeQueue)).andReturn(something).times(100);
replayAll();

// The actual method to test
TestClass myTestInstance = new TestClass(myClass);
myTestInstance.testMethod(queueFactory, multimap);
myTestInstance.testMethod(queueFactory, multimap);

这是我正在测试的方法:

public class MyTestClass
    private MyClass myClass;

    public MyTestClass(MyClass myClass) {
        this.myClass = myClass;
    }

    public void testMethod(QueueFactory queueFactory, Multimap<String, String> multimap) {
        BlockingQueue<MyType> myTypeQueue = queueFactory.getQueue(100);
        BlockingQueue<MyOtherType> myOtherTypeQueue = queueFactory.getQueue(100);

        for (int i = 0; i < 50; ++i) {
            myClass.myMethod("en", multimap, myTypeQueue, myOtherTypeQueue);
        }
    }
}

到目前为止,我已经尝试用 HashMultimap 和 ArrayBlockingQueue 的实例替换模拟。我还尝试将所有方法参数包装在EasyMock.eq 中。这两种方法都没有解决这个问题。

任何想法为什么会发生这种情况?

【问题讨论】:

  • 你在哪里调用方法?
  • MyClass.myMethod 的调用发生在我正在测试的方法中。我正在测试的方法是在replayAll() 之后调用的
  • 让我们看看它并发布完整的堆栈跟踪。
  • 这是完整的堆栈跟踪。我更新了测试以显示更多内容。
  • 您的测试报告myClass.myMethod 未被调用。所以告诉我们它是。

标签: java easymock


【解决方案1】:

由于类型擦除,EasyMock 无法确定这一点

expect(queueFactory.<MyType>getQueue(100))

不同于

expect(queueFactory.<MyOtherType>getQueue(100))

每个expect 调用都会按顺序注册对多个调用的期望。所以

expect(queueFactory.<MyType> getQueue(100)).andReturn(myTypeQueue).times(2);

声明前两次调用getQueue(100),它将返回myTypeQueue。如果你按照

expect(queueFactory.<MyOtherType> getQueue(100)).andReturn(myOtherTypeQueue).times(1);

接下来对getQueue(100) 的两次调用将返回myOtherTypeQueue

在您的testMethod 中,您调用

BlockingQueue<MyType> myTypeQueue = queueFactory.getQueue(100);
BlockingQueue<MyOtherType> myOtherTypeQueue = queueFactory.getQueue(100);

调用getQueue(100) 两次,即。前两次。这些都将返回myTypeQueue,这打破了对myClass.myMethod 的期望。

只执行一次即可,因为第一个expect 返回myTypeQueue,第二个返回myOtherTypeQueue,这与您对myClass.myMethod 的期望相符。

您可以通过按顺序注册每个来修复它,一次

expect(queueFactory.<MyType> getQueue(100)).andReturn(myTypeQueue).times(1);
expect(queueFactory.<MyOtherType> getQueue(100)).andReturn(myOtherTypeQueue).times(1);
expect(queueFactory.<MyType> getQueue(100)).andReturn(myTypeQueue).times(1);
expect(queueFactory.<MyOtherType> getQueue(100)).andReturn(myOtherTypeQueue).times(1);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-06
    • 1970-01-01
    • 2011-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多