【问题标题】:Setting up a Mockery's Expectations in relation to protected methods设置与受保护方法相关的 Mockery 期望
【发布时间】:2012-05-08 18:22:55
【问题描述】:

我在尝试设置 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)。这会在内存中创建两个不同的事件...该错误是否与它期望该方法获取一个事件但接收到另一个事件的可能性有关?

*****编辑

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

【问题讨论】:

  • 尝试模拟类而不是接口context.mock(MySource.class);
  • 我在发帖之前尝试模拟事件,它说我只能模拟实例。我阅读了关于模拟类的信息(如果您将setImposteriser(ClassImposteriser.INSTANCE); 添加到模拟创建中,则可以使用。我对 TDD 比较陌生,但这似乎不像这里的正确方法。但我会试一试。我顺便说一句,不想模拟源,因为那是被测对象。
  • 另外,当我改变我必须使 handleMyEvent() 方法可见时,它会说我只能对模拟事件设置期望。所以我很困惑它为什么抱怨在非模拟对象中意外调用了某些东西。

标签: java methods protected jmock infinitest


【解决方案1】:

事实证明,我怀疑这与创建了两个不同的 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();
}

【讨论】:

    猜你喜欢
    • 2020-11-11
    • 2012-02-29
    • 1970-01-01
    • 2020-03-31
    • 2015-11-21
    • 2012-08-06
    • 2016-02-19
    • 2011-10-26
    • 1970-01-01
    相关资源
    最近更新 更多