JMockit - 两个相同类型的模拟实例

时间:2011-04-20 12:08:07

标签: java unit-testing testing mocking jmockit

我正在使用JMockit框架,我正在尝试测试我的简单EventBus实现,该实现允许EventHandlers注册Event类型。当事件在事件总线上为fired时,所有注册的处理程序都会收到通知。事件处理程序可以消耗事件,这将导致后续处理程序不会被通知事件。

我的测试方法如下:

// The parameter secondHandler should be mocked automatically by passing it
// as an argument to the test method
@Test
public void testConsumeEvent(final EventHandler<TestEvent> secondHandler)
{
    // create the event which will be fired and which the handlers are
    // listening to
    final TestEvent event = new TestEvent();

    // this handler will be called once and will consume the event
    final EventHandler<TestEvent> firstHandler = 
        new MockUp<EventHandler<TestEvent>>()
        {
            @Mock(invocations = 1)
            void handleEvent(Event e)
            {
                assertEquals(event, e);
                e.consume();
            }
    }.getMockInstance();

    // register the handlers and fire the event
    eventBus.addHandler(TestEvent.class, firstHandler);
    eventBus.addHandler(TestEvent.class, secondHandler);
    eventBus.fireEvent(event);

    new Verifications()
    {
        {
            // verify that the second handler was NOT notified because
            // the event was consumed by the first handler
            onInstance(secondHandler).handleEvent(event);
            times = 0;
        }
    };
}

当我尝试运行此代码时,我得到以下异常:

java.lang.IllegalStateException: Missing invocation to mocked type at this 
point; please make sure such invocations appear only after the declaration
of a suitable mock field or parameter

异常发生在times = 0行上,我不知道为什么因为类型secondHandler应该被模拟,因为它作为参数传递给测试方法。向参数添加@Mocked@Injectable没有任何区别。

如果我从firstHandler创建一个标准类,它将只使用该事件,然后测试代码,一切运行正常。但在这种情况下,我无法明确验证调用firstHandler的方法handleEvent,因为它不再是模拟类型。

非常感谢任何帮助,谢谢!

1 个答案:

答案 0 :(得分:1)

我自己找到了问题的解决方案。修复非常简单,我只需要将Verifications块转换为Expectations块,并在模拟firstHandler的初始化之前将其放置。

在我看来,语句new MockUp<EventHandler<TestEvent>>()模仿了每种类型的EventHandler<TestEvent>并覆盖了已定义的实例,即我的secondHandler。我是否正确,或者是否是我不知道的错误或功能。

如果有人知道究竟发生了什么,请对此答案发表评论。谢谢!