๐ด The Error You're Seeing
Confirm this matches your console output. If it does, you're in the right place.
org.mockito.exceptions.misusing.NotEnoughInvocationsError:
UserService.save("Deva");
Wanted 2 times:
-> at com.devinhyderabad.UserServiceTest.testSave(UserServiceTest.java:45)
But was 1 time:
-> at com.devinhyderabad.UserService.save(UserService.java:20)โก Quick Fix Works 80% of the time
Change your verify() statement to expect 1 invocation, or fix your test logic to trigger the method twice.
verify(userService, times(1)).save("Deva");๐ง Why this Happens
Tap to expand the deep technical explanation
You used Mockito's `verify(mock, times(2))` to assert that a specific method was called exactly twice during the test. However, the code under test only called that method once. This means either your test logic didn't trigger the expected behavior, or your expectation was wrong.
The HITEC City Parking Spot Analogy:
It's like a security guard checking the logbook, expecting an employee to badge in twice (once on entry, once on exit). If the employee only badged in once, the guard throws an error because the log doesn't match the expectation.
๐ How to Reproduce Confirm this is your error
Mock a `UserService`. In your test, call `userService.save("Deva")` exactly once. Assert `verify(userService, times(2)).save("Deva")`. Run the test.
๐ ๏ธ Solutions (5 Ways to Fix)
Fix the expected invocation count
๐ Use this if you overestimated how many times the method should be called.
Change `times(2)` to `times(1)` (or simply omit the verification mode, as `verify(mock)` defaults to `times(1)`).
verify(userService, times(1)).save("Deva");
// OR
verify(userService).save("Deva");Fix the test logic to trigger the method
๐ Use this if the method *should* have been called twice, but your test didn't trigger it.
Trace your test code to ensure the loop or conditional logic actually executes the method the expected number of times.
// Test logic:
userController.processBatch(Arrays.asList(req1, req2)); // This should call save() twice
verify(userService, times(2)).save(any());Use atLeast() or atMost() for flexibility
๐ Use this if you don't know the exact number, but know the bounds.
Loosen the verification to accept a range of invocations.
verify(userService, atLeast(1)).save(any());
verify(userService, atMost(5)).save(any());Check for swallowed exceptions
๐ Use this if the method was supposed to be called twice, but an exception stopped the loop.
If an exception was thrown and caught silently during the second iteration, the method was only called once. Fix the exception.
// Check your service code for try-catch blocks that might be swallowing errors:
try {
save(user);
} catch (Exception e) {
log.error("Error", e); // Swallowed! Second call never happens.
}Verify with different arguments
๐ Use this if the method was called twice, but with different arguments than you expected.
Mockito matches exact arguments. If the second call used a different object, `verify(mock, times(2)).save(specificUser)` will fail.
verify(userService, times(2)).save(any(User.class)); // Use matchers instead of exact objects๐ Version Notes
Uses Mockito 3.x/4.x.
Uses Mockito 5.x. Same error, but stricter inline mocking.
๐ก๏ธ How to Prevent This Next Time
Write clear test step comments. Verify only the interactions that are critical to the specific test case to avoid brittle tests.