Does java.util Optional.ofNullable works properly with Mockito?
During the code execution I encounter something like this:
User user = Optional.ofNullable(userProviderMock.findUser()).orElse(someMethod())
I set my mock behaviour like following:
when(userProviderMock.findUser()).thenReturn(new User());
When I run it, userProviderMock returns new User() (debug confirms that), but somehow someMethod() is still executed.
I have literally no idea why this is happening. Any clues?
Mockito and ofNullable aren't really at issue here. Consider this code:
Optional.of("foo").orElse(someMethod())
The above code will evaluate to Optional.of("foo") — but it still calls orElse, so it still has to call someMethod() in order to pass its return-value as an argument to orElse, even though that argument ends up not being used.
If this is a problem for you — if you don't want someMethod() to be called unless its return-value is actually needed — then you should use orElseGet instead:
Optional.of("foo").orElseGet(() -> someMethod())
or rather:
User user = Optional.ofNullable(userProviderMock.findUser()).orElseGet(() -> someMethod())
Edited to add: Didier L points out that () -> someMethod() can also be written as this::someMethod (that is: we can write it as a method reference rather than a lambda), which is probably more readable.
Either way, it gets converted implicitly to approximately this:
User user = Optional.ofNullable(userProviderMock.findUser()).orElseGet(new Supplier<User>() {
public User get() {
return someMethod();
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With