Using verifyNoMoreInteractions works unless there is a "when" clause using that mock

3,410 views
Skip to first unread message

David Karr

unread,
Jan 15, 2019, 12:10:07 PM1/15/19
to mockito
In some tests I'm working on, I've been experimenting with putting "verifyNoMoreInteractions(mock)" after the set of "verify" statements, as a way of ensuring that only the specified set of interactions are occurring, and nothing else.

Most of the test methods in this particular test class only have "verify" clauses.  A handful have a "when" clause or two.

What I'm finding is that "verifyNoMoreInteractions(mock)" works fine if the test method only specifies "verify" clauses using that mock. If there's at least one "when" clause using that mock, I get a "NoInteractionsWanted" exception.

I imagine I'm misunderstanding how this has to work.

David Karr

unread,
Jan 16, 2019, 3:03:41 PM1/16/19
to mockito
I think I'm understanding this a little better, but I still wish there was a cleaner way to do this.

I also have an example to illustrate this.

public class Bar {
   
private Foo foo;
   
   
public Foo getFoo() { return foo; }
   
public void setFoo(Foo foo) { this.foo = foo; }

   
public void getSomethingAndDoSomething() {
       
int stuff   = foo.getSomething();
        foo
.doSomething();
   
}
   
   
public void doSomething() { foo.doSomething(); }
}

public class Foo {
   
public int getSomething() { return 1; }
   
public void doSomething() { }
}

@RunWith(MockitoJUnitRunner.class)
public class BarTest {
   
@Mock
   
private Foo foo;
   
@InjectMocks
   
private Bar bar;

   
@Test
   
public void getSomethingAndDoSomething() throws Exception {
       
when(foo.getSomething()).thenReturn(3);
       
        bar
.getSomethingAndDoSomething();
       
        verify
(foo).doSomething();
        verify
(foo).getSomething();
       
        verifyNoMoreInteractions
(foo);
   
}
   
   
@Test
   
public void doSomething() throws Exception {
        bar
.doSomething();
       
        verify
(foo).doSomething();
        verifyNoMoreInteractions
(foo);
   
}
}


As provided, these tests pass. However, I don't like what I had to do in "getSomethingAndDoSomething" in the test class. I have a "when" clause that specifies behavior of the "getSomething" method, and I ALSO have a "verify" clause for that same method. The presence of the "when" clause essentially guarantees that the call to "getSomething" was done. If I commented out the actual call to "getSomething" in the "Bar" class, the test would fail with a "Wanted but not invoked" exception.

If I instead comment out the "verify(foo).getSomething()" call, I get a "No interactions wanted here" exception from the "verifyNoMoreInteractions", even though this occurred AFTER the call to "getSomething()".

So, I guess I understand now that "verifyNoMoreInteractions" doesn't quite mean "there were no more interactions with this mock", even though that's what it says, but that's really what I want it to mean.
Reply all
Reply to author
Forward
0 new messages