使用EasyMock和递归方法

时间:2014-02-11 00:04:11

标签: java recursion mocking easymock

我使用EasyMock 3.2生成的一系列Strict Mocks来测试一个递归调用自身的方法。通过设置我的模拟的期望,我可以控制方法,以便它只调用自己一次然后退出。但是,我看到一些来自EasyMock的非常奇怪的行为,它看起来像一个bug,它让人对预期方法的次数感到困惑。

例如:

final Collection srcCollection = EasyMock.createStrictMock(Collection.class);
final NativeBroker broker = EasyMock.createMockBuilder(NativeBroker.class)
    .addMockedMethod("getCollection")
    .addMockedMethod("getSubject")
    .createStrictMock();

expect(srcCollection.getURI()).andReturn(src);

replay(srcCollection, broker);

//run the test
broker.checkPermissionsForCopy(srcCollection, dest, newName);

verify(srcCollection, broker);

导致EasyMock出错:

java.lang.AssertionError: 
    Expectation failure on verify:
        Collection.getURI(): expected: 2, actual: 1
        at org.easymock.internal.MocksControl.verify(MocksControl.java:226)
        at org.easymock.EasyMock.verify(EasyMock.java:2080)

我只是指示EasyMock期待一个结果,为什么它认为我想要两个?如果我改变对此的期望,我也会得到同样的错误:

expect(srcCollection.getURI()).andReturn(src).once();

......它变得陌生......

如果我改变对此的期望:

expect(srcCollection.getURI()).andReturn(src).times(2);

我收到错误:

java.lang.AssertionError: 
    Expectation failure on verify:
        Collection.getURI(): expected: 3, actual: 1
        at org.easymock.internal.MocksControl.verify(MocksControl.java:226)
        at org.easymock.EasyMock.verify(EasyMock.java:2080)

而且,如果我改变对此的期望:

expect(srcCollection.getURI()).andReturn(src).anyTimes();

我得到一个更奇怪的错误:

java.lang.IllegalStateException: last method called on mock already has a non-fixed count set.
    at org.easymock.internal.MocksControl.replay(MocksControl.java:216)
    at org.easymock.EasyMock.replay(EasyMock.java:2012)

有没有人有任何建议,或者知道EasyMock在递归函数中有任何限制?

3 个答案:

答案 0 :(得分:4)

在我的情况下,我重复了相同的预期值2次。它抛出:

java.lang.IllegalStateException:在mock上调用的最后一个方法已经有一个非固定的计数集。

<强> E.G。

SchedulingDataForVersion dataForVersion = createNiceMock(SchedulingDataForVersion.class);
TaskSource mockedTaskSource = createNiceMock(TaskSource.class);

    expect(mockedTaskSource.getOrderElement()).andReturn(orderLine).anyTimes();
    expect(mockedTaskSource.getOrderElement()).andReturn(orderLine).anyTimes();

    replay(dataForVersion, mockedTaskSource);

正确一个是:

SchedulingDataForVersion dataForVersion = createNiceMock(SchedulingDataForVersion.class);
TaskSource mockedTaskSource = createNiceMock(TaskSource.class);

    expect(dataForVersion.getOrderElement()).andReturn(orderLine).anyTimes();
    expect(mockedTaskSource.getOrderElement()).andReturn(orderLine).anyTimes();

    replay(dataForVersion, mockedTaskSource

答案 1 :(得分:0)

我看不出这段代码有什么问题。

预计代理上的两个模拟方法是否会被调用?

我做了一个测试用例。你能让它失败吗?

public class AppTest {

public static interface Collection {
    String getURI();
}

public static class NativeBroker {

    public void checkPermissionsForCopy(Collection srcCollection, String dest,
            String newName) {
        srcCollection.getURI();
    }

    public Collection getCollection() {
        return null;
    }

    public String getSubject() {
        return null;
    }
}

String src = "http://src.com";
String dest = "http://dest.com";
String newName = "my name";

@Test
public void testApp() {
    final Collection srcCollection = EasyMock.createStrictMock(Collection.class);
    final NativeBroker broker = EasyMock.createMockBuilder(NativeBroker.class)
            .addMockedMethod("getCollection")
            .addMockedMethod("getSubject")
            .createStrictMock();

    expect(srcCollection.getURI()).andReturn(src);

    replay(srcCollection, broker);

    // run the test
    broker.checkPermissionsForCopy(srcCollection, dest, newName);

    verify(srcCollection, broker);
}}

答案 2 :(得分:0)

当您添加.anyTimes()然后写相同的调用时,就会发生错误。

expect(mock.get()).andReturn("string").anyTimes();->具有多个支持的首次通话 expect(mock.get()).andReturn("string");->不需要第二次呼叫

解决方案是仅编写具有多个支持的第一个呼叫

expect(mock.get()).andReturn("string").anyTimes();