Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mockito "verify" checks current state, but does not reset mock invocations

I'm using Mockito in my JUnit tests. The test is an integration test, testing a whole scenario, thus there are many assertions and verify(mock)s in it.

My problem is, that I'm writing some production code, doing some assertions and then verify the mock which works, until there is an identical mock invocation. see the simplified code:

interface I {
    void m1();
    void m2();
}

// some decorator
class T implements I {
    public T(I decorated) {
        /*...*/
    }

    /* ... */
}

public void testInvalid() {
    I m = mock(I.class);
    T t = new T(m);

    t.m1();
    assertEquals("m1", t.getLastMethod());
    verify(m).m1();

    t.m2();
    assertEquals("m2", t.getLastMethod());
    verify(m).m2();

    t.m1();
    assertEquals("m1", t.getLastMethod());
    verify(m).m1();

    // TooManyActualInvocations t.m1(): Wanted 1 time, but was 2 times ...
}

public void testValid() {
    I m = mock(I.class);
    T t = new T(m);

    t.m1();
    assertEquals("m1", t.getLastMethod());

    t.m2();
    assertEquals("m2", t.getLastMethod());

    t.m1();
    assertEquals("m1", t.getLastMethod());

    verify(m, times(2)).m1();
    verify(m).m2();
}

One idea is to verify the mocks at the end, but let's say there is a small stupid implementation mistake which leads to invoking the method m1 twice and m2 once but not as I would expect it in testInvalid but in the end the test would pass. I want my test to fail early. How do I accomplish that?

Thank you.

Thanks to @Woozy Coder:

Didn't mentioned, that reset would also be an option, but since it has to be called between verify and the next equal stub call, it makes it hard to write "nice" and correct tests, I think. There should be two different mocking styles:

  1. "postcondition" mocking as Mockito does it
  2. "early" mocking which would be an implicit reset after a verify-block

something like:

earlyReset(m).after(
    new Runnable() {
        t.someMethodInvokingTwoStubs();

        verify(m).someMethod1();
        verify(m).someMethod2();
    }
);
like image 691
Aitch Avatar asked Sep 05 '25 11:09

Aitch


1 Answers

I am having a similar problem and decided to use clearInvocations() (arrived in Mockito 2.1)

https://javadoc.io/static/org.mockito/mockito-core/3.3.3/org/mockito/Mockito.html#clearInvocations-T...-

Using reset() has the drawback that you loose your stubbing as well, clearInvocations() only clears the invocations.

like image 178
longliveenduro Avatar answered Sep 08 '25 19:09

longliveenduro