Reputation: 2499
In Mockito, is there a way to verify that there are no more interactions on any mock I have created?
For example:
public void test()
{
...
TestObject obj = mock(TestObject);
myClass.test();
verifyNoMoreInteractionsWithMocks(); <-------
}
Is there such a method?
Upvotes: 40
Views: 73959
Reputation: 1
Thanks for the great example! I modified the code a little, remade the class into Singleton. Otherwise, there may be a problem when using MockCollector in multiple test classes.
import org.mockito.Mockito;
import org.mockito.internal.progress.ThreadSafeMockingProgress;
import org.mockito.listeners.MockCreationListener;
import java.util.LinkedList;
import java.util.List;
public final class MocksCollector {
private final List<Object> createdMocks;
private MocksCollector() {
createdMocks = new LinkedList<>();
final var progress = ThreadSafeMockingProgress.mockingProgress();
progress.addListener((MockCreationListener) (mock, settings) -> createdMocks.add(mock));
}
private static final class InstanceHolder {
private static final MocksCollector INSTANCE = new MocksCollector();
}
public static MocksCollector getInstance() {
return InstanceHolder.INSTANCE;
}
public Object[] getMocks() {
return createdMocks.toArray();
}
public void reset() {
for (Object createdMock : createdMocks) {
Mockito.reset(createdMock);
}
}
}
use it
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.mockito.Mockito.verifyNoMoreInteractions;
@ExtendWith(MockitoExtension.class)
class ServiceTest {
// Some mocked services and SUT...
private static final MocksCollector mocksCollector = MocksCollector.getInstance();
@Test
void test() {
// given
mocksCollector.reset();
// when
this.service.someAction();
// then
verifyNoMoreInteractions(mocksCollector.getMocks());
}
}
Upvotes: 0
Reputation: 29520
Since verifyNoMoreInteractions take an array of object we have to find a way to get all the created mocks.
You can create this class
public class MocksCollector {
private final List<Object> createdMocks;
public MocksCollector() {
createdMocks = new LinkedList<Object>();
final MockingProgress progress = new ThreadSafeMockingProgress();
progress.setListener(new CollectCreatedMocks(createdMocks));
}
public Object[] getMocks() {
return createdMocks.toArray();
}
}
and then use it in your test :
public class ATest {
private final MocksCollector mocksCollector = new MocksCollector();
@Test
public void test() throws Exception {
A a1 = mock(A.class);
A a2 = mock(A.class);
A a3 = mock(A.class);
assertEquals("wrong amount of mocks", 3, mocksCollector.getMocks().length);
verifyNoMoreInteractions(mocksCollector.getMocks());
a3.doSomething();
verifyNoMoreInteractions(mocksCollector.getMocks()); // fail
}
}
or with annotations :
@RunWith(MockitoJUnitRunner.class)
public class A2Test {
private final MocksCollector mocksCollector = new MocksCollector();
@Mock
private A a1;
@Mock
private A a2;
@Mock
private A a3;
@Test
public void test() throws Exception {
assertEquals("wrong amount of mocks", 3, mocksCollector.getMocks().length);
verifyNoMoreInteractions(mocksCollector.getMocks());
a2.doSomething();
verifyNoMoreInteractions(mocksCollector.getMocks()); // fail
}
}
It works but it adds a dependency on mockito internal.
Upvotes: 50