EasyMock在预期调用时表示意外调用

时间:2014-12-24 13:34:48

标签: java easymock

我在使用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中的所有方法参数包装起来。这些方法都没有解决这个问题。

为什么会发生这种情况?

1 个答案:

答案 0 :(得分:2)

由于类型擦除,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);