-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Description
Version affected: Mockito: 4.x & 5.x
If you create a mock with RETURN_DEEP_STUBS, then any method that returns a collection will, by default, return an empty collection, i.e. isEmpty returns true, etc. This is great, as it means no additional configuration of the mock is required before passing to logic that would attempt to access elements of the collection.
However, the same is not true for Optional, (and I'm assuming OptionalLong etc): if RETURN_DEEP_STUBS is used, methods that return Optional aren't treated in any special way and just return a default mock with not stubbing configured. This means isEmpty returns false, but get() returns null. This breaks the contract of Optional, causing test failures that aren't actually valid, or requiring manual configuration of the Optional mock to do-the-right-thing, cluttering test code.
Here's an example test that demonstrates this:
interface Address {
Optional<String> getState();
}
@Test
public void shouldDefaultDeepMockOptionalsToEmpty() {
final Address address = mock(Address.class, RETURNS_DEEP_STUBS);
assertThat(address.getState()).isEqualTo(Optional.empty()); // <--- fails
}
@Test
public void shouldDefaultMockOptionalsToEmpty() {
final Address address = mock(Address.class); // <-- no RETURNS_DEEP_STUBS
assertThat(address.getState()).isEqualTo(Optional.empty()); // <--- passes
}Note the second test, which doesn't use deep mocking, passes.
- The mockito message in the stacktrace have useful information, but it didn't help
- The problematic code (if that's possible) is copied here;
Note that some configuration are impossible to mock via Mockito - Provide versions (mockito / jdk / os / any other relevant information)
- Provide a Short, Self Contained, Correct (Compilable), Example of the issue
(same as any question on stackoverflow.com) - Read the contributing guide