janhink
janhink

Reputation: 5023

JMockit - two mocked instances of the same type

I'm using the JMockit framework and I'm trying to test my simple EventBus implementation which allows EventHandlers to be registered for Event types. When an event is fired on the event bus, all registered handlers get notified. An event can be consumed by an event handler which will cause that subsequent handlers will NOT be notified of the event.

My test method looks like this:

// 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;
        }
    };
}

When I try to run this code I get the following exception:

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

The exception occurs on the line times = 0 and I don't know why since the type secondHandler should be mocked because it's passed as a parameter to the test method. Adding @Mocked or @Injectable to the parameter makes no difference.

If I make a standard class from the firstHandler, which will just consume the event, and then test the code, everything runs just fine. But in that case I can't verify explicitly that the firstHandler's method handleEvent is called because it's not a mocked type anymore.

Any help is much appreciated, thanks!

Upvotes: 0

Views: 6457

Answers (1)

janhink
janhink

Reputation: 5023

I have found solution of the problem myself. The fix was rather simple, I just needed to transform the Verifications block into an Expectations block and put it BEFORE the initialization of the mocked firstHandler.

It seems to me that the statement new MockUp<EventHandler<TestEvent>>() mocks every type of EventHandler<TestEvent> and overrides already defined instances, i.e. my secondHandler. Whether I'm correct or not or whether it's a bug or a feature I don't know.

If someone knows what exactly is going on, please comment on this answer. Thanks!

Upvotes: 1

Related Questions