Search code examples
javamockitojukito

Missing method call for verify(mock), but there is one?


Introduction

I'm attempting to make a test which verifies (using Mockito v1.9.5's verify) that a method with signature deinit() in an interface Bar is called after execution of a pass-through Foo.deinit(), and I'm hitting an error I really don't understand.

Here's the FooTest.java which I'm attempting to run:

@RunWith(JukitoRunner.class)
public class FooTest {
    @Inject
    private Foo foo;
    @Inject
    private Bar bar;

    public static class TestModule extends JukitoModule {
        @Override
        protected void configureTest() {
            bind(Foo.class).to(FooImpl.class);
            bind(Bar.class).to(BarImpl.class);
            bindSpy(BarImpl.class);
        }
    }

    @Test
    public void testDeinit() {
        foo.init(mock(Baz.class));
        foo.deinit();
        verify(bar).deinit();
    }

    @After
    public void validate() {
        validateMockitoUsage(); //line YY
    }
}

When running this, testDeinit() fails with the following error:

org.mockito.exceptions.misusing.UnfinishedVerificationException:
Missing method call for verify(mock) here:
  -> at redacted.impl.BarImpl.deinit(BarImpl.java:XX)
  
Example of correct verification:
  verify(mock).doSomething()
  
Also, this error might show up because you verify either of: final/private/equals()/hashCode() methods. 
Those methods *cannot* be stubbed/verified. 

at redacted.impl.FooTest.validate(FooTest.java:YY)
at org.jukito.InjectedStatement.evaluate(InjectedStatement.java:96)
at org.jukito.InjectedAfterStatements.evaluate(InjectedAfterStatements.java:58)
at org.jukito.jukitoRunner.run(JukitoRunner.java:197)

Which I haven't been able to extract much useful information from. It seems almost as if the error complains that verify(bar).deinit() might as well not have a .deinit() off the end, and I can remove that portion and get an identical error. The example provided in the error message is especially frustrating, as it appears almost identical to my use of verify.

Details

Here's my BarImpl.java

public class BarImpl implements Bar {
    private final Qux qux;
    private final Quux quux;

    @Inject
    public BarImpl(final Qux qux, final Quux quux) {
        this.qux = qux;
        this.quux = quux;
    }

    @Override
    private final void init(Baz baz) {
        quux.init(this);
        qux.init();
    }

    @Override
    public final void deinit() {
        qux.deinit();  //line XX
    }
}

I'm still unclear how the qux.deinit() causes failure here. Here's my FooImpl.java:

class FooImpl implements Foo {
    private final Bar bar;

    @Inject
    public FooImpl(final Bar bar) {
        this.bar = bar;
    }

    @Override
    public void init(Baz baz) {
        bar.init(baz);
    }

    @Override
    public void deinit() {
        bar.deinit(); 
    }
}

Question

What's causing the UnfinishedVerificationException and how can it be fixed?

I'm a Mockito newb so it's very likely I've missed something fundamental. Please let me know if there's more information I can provide. Sorry if this has been answered already and I've misunderstood answers here on SO.


Solution

  • Actually your problem is in the error message:

    Also, this error might show up because you verify either of: final/private/equals()/hashCode() methods. Those methods cannot be stubbed/verified.

    Indeed you try to implicitly verify calls to BarImpl#deinit which is a final method and Mockio doesn't support final method mocking as explained into the doc. If you want to verify it you need either to remove the keyword final from the declaration of BarImpl#deinit or use Powermock instead.