设置与受保护方法相关的Mockery期望

时间:2012-05-08 18:22:56

标签: java methods protected jmock infinitest

我遇到了尝试设置Mockery以测试方法调用的问题。我看到了How to test protected methods of abstract class using JUnit and JMock,这基本上是同一个问题,但我无法弄清楚克里斯在他的回答中指的是什么。如果可以,请让某人以稍微不同的方式或更完整的英语向我解释。我正在使用JUnit,JMock2,Infinitest(如果这很重要),以及基于事件的标准消息系统如下:

public Interface MyEventListener {
    void handleMyEvent(MyEvent e);
}

public Class MyEvent extends EventObject {
    public MyEvent(Object source) {
        super(source);
    }
}

public Class MySource {
    protected List<MyEventListener> listeners = new ArrayList<MyEventListeners>();

    public void addListener(MyEventListener listener) {
        listeners.add(listener);
    }

    public void removeListener(MyEventListener listener) {
        listeners.remove(listener);
    }

    // other code...

    protected void raiseEvent() {
        for (MyEventListener listener : listeners) {
            listener.handleMyEvent(new MyEvent(this));
        }
    }
}

现在这是我的测试:

@Test
public void sourceShouldThrowEventOnEventOccurrence() {
    // set up
    Mockery context = new Mockery();
    MyEventListener listener = context.mock(MyEventListener.class);
    MySource source = new MySource();
    MyEvent event = new MyEvent(source);
    source.addListener(listener);

    // set expectations
    context.checking(new Expectations() {{
        oneOf(listener).handleMyEvent(event);
    }});

    // execute
    // do stuff to (theoretically) raise event

    // verify
    context.assertIsSatisfied();
}

我在MySource中的raiseEvent()受保护方法上得到ExpectationError(意外调用)。我怎样才能增加它应该调用受保护方法的期望?

另外,我刚想到了一个想法 - 但是在我去探索它之前我仍然会发布这条消息(以防其他人有同样的问题,我的想法最终是对的)。错误可能与我的代码中有两个新关键字的事实有关吗?我在MySource.raiseEvent()中有新的MyEvent(this),然后我在测试中有了新的MyEvent(source)。这会在内存中创建两个不同的事件...错误是否与预期方法获取一个事件但接收另一个事件的可能性有关?

***** EDIT

实际上,具体来说,我在实际引发事件的代码行上得到了ExpectationError(意外调用)。 (在我上面的代码中,listener.handleMyEvent(new MyEvent(this));行)

1 个答案:

答案 0 :(得分:0)

我怀疑它与创建两个不同的MyEvent实例是正确的事实有关。不幸的是,这意味着我的问题的标题是误导性的。在挖掘之后,我发现我的代码工作正常,一旦我将Expectations()更改为以下内容。

@Test
public void sourceShouldThrowEventOnEventOccurrence() {
    // set up
    Mockery context = new Mockery();
    MyEventListener listener = context.mock(MyEventListener.class);
    MySource source = new MySource();
    // MyEvent event = new MyEvent(source);  <-- NO LONGER NEEDED
    source.addListener(listener);

    // set expectations
    context.checking(new Expectations() {{
        oneOf(listener).handleMyEvent(with(any(MyEvent.class)));  // <-- with any
    }});

    // execute
    // do stuff to (theoretically) raise event

    // verify
    context.assertIsSatisfied();
}