Mockito verify no more interactions with any mock
Asked Answered
D

2

39

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?

Doorframe answered 17/8, 2012 at 21:2 Comment(1)
See #512754Teem
A
49

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.

Applecart answered 17/8, 2012 at 21:37 Comment(2)
This work great. The only problem is that when you use the @Mock annotation, it is not collected in the MocksCollector.Doorframe
It looks like only @RunWith(PowerMockRunner.class) fails, while @RunWith(MockitoJUnitRunner.class) works fine.Doorframe
C
0

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());
    }
}
Cristobal answered 24/7 at 10:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.