Search code examples
javaspring-boottestingjunitmockito

Mockito Test Fails with 'Wanted but not Invoked; Actually, there were zero interactions' Error


I'm facing issues with a unit test in a Spring Boot application where a specific repository method isn't being called as expected during the test of a service method. Despite setting up the test with Mockito, the repository method seems to be skipped.

Here is the error that I get:

19:47:54.914 [Test worker] DEBUG org.reactor.util.Loggers - Using Slf4j logging framework
19:47:54.963 [Test worker] INFO com.myapp.service.EntityManagementService - No entity found for reference number: referenceNumber

Wanted but not invoked:
entityRepository.findByRefNumber("referenceNumber");
-> at com.myapp.service.EntityManagementServiceTest.shouldInvokeRepositoryWhenProcessingEntityUpdate(EntityManagementServiceTest.java:150)
Actually, there were zero interactions with this mock.

I am testing a service method that processes status updates and interacts with a GraphQL client for further operations. The service method *processStatusChange* should fetch an entity using the repository method *findEntityByRef*. However, even though I mock this method to return a specific object, it behaves as if it's not finding the entity.

Here's a simplified version of the service method and the test setup:

Service Method:

    @Autowired
    private EntityRepository entityRepository;

    public void processEntityUpdate(String refNumber) {
        Optional<Entity> entityOptional = entityRepository.findByRefNumber(refNumber);
        if (entityOptional.isEmpty()) {
            log.info("Entity not found for reference number: {}", refNumber);
            return;
        }
        Entity entity = entityOptional.get();
        updateEntityDetails(entity);
    }

    protected void updateEntityDetails(Entity entity) {
        // Interaction with GraphQL client to update details
    }
}

Test Setup:

@ExtendWith(MockitoExtension.class)
public class EntityManagementServiceTest {
    @Mock
    private EntityRepository entityRepository;

    @InjectMocks
    @Spy
    private EntityManagementService entityManagementService;

    @BeforeEach
    void setUp() {
        MockitoAnnotations.openMocks(this);
        Entity mockEntity = new Entity();
        mockEntity.setRefNumber("referenceNumber");
        when(entityRepository.findByRefNumber("referenceNumber")).thenReturn(Optional.of(mockEntity));
    }

    @Test
    void shouldInvokeRepositoryWhenProcessingEntityUpdate() {
        entityManagementService.processEntityUpdate("referenceNumber");
        verify(entityRepository).findByRefNumber("referenceNumber");
    }
}

I expected *findEntityByRef* to be called and the test to verify its invocation, but the test fails stating the method was not invoked.

I have set up my test using @Spy and @InjectMocks on the service to both use real method implementations and mock dependencies. This is particularly necessary because the method updateEntityStatus inside the StatusService class interacts with another method that constructs a GraphQL client, which I also need to test.


Solution

  • I think the initialization of your mocks goes wrong (or happening twice). You should either use the class annotation "@ExtendWith(MockitoExtension.class)" or do the manual initialization with "MockitoAnnotations.openMocks(this)". So the simple answer could be: Just remove "MockitoAnnotations.openMocks(this)".