Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Optional.ofNullable with Mockito

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?

like image 318
krzakov Avatar asked Mar 06 '26 15:03

krzakov


1 Answers

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();
    }
});
like image 197
ruakh Avatar answered Mar 08 '26 04:03

ruakh



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!