I am trying to test a method that takes a Consumer
function, and I want to verify with Mockito that my lambda expression is called exactly once. What I'm using now is the kind of clunky way of using a flag on a final, single-element array:
final boolean[] handlerExecuted = {false};
instance.conditionalRun(item -> {
handlerExecuted[0] = true;
item.foo();
});
Assert.assertTrue(
"Handler should be executed.",
handlerExecuted[0]);
It seems like there should be a better way (with a Mockito spy, perhaps) to verify that this lambda expression was called exactly once.
Some of the other answers offer alternatives to doing exactly what I want here, but this is doable by Spying the Consumer
class itself and having the spy call the method you really want to execute. A helper method for wrapping the lambda to create the spy helps here:
/** Get a spied version of the given Consumer. */
private Consumer<Item> itemHandlerSpy(Consumer<Item> itemHandler) {
// Create a spy of the Consumer functional interface itself.
@SuppressWarnings("unchecked")
Consumer<Item> spy = (Consumer<Item>) Mockito.spy(Consumer.class);
// Tell the spy to run the given consumer when the Consumer is given something to consume.
Mockito.doAnswer(it -> {
// Get the first (and only) argument passed to the Consumer.
Item item = (Item) it.getArguments()[0];
// Pass it to the real consumer so it gets processed.
itemHandler.accept(item);
return null;
}).when(spy).accept(Mockito.any(Item.class));
return spy;
}
And then the test method becomes very straightforward:
Consumer<Item> itemHandler = itemHandlerSpy(Item::foo);
instance.conditionalRun(itemHandler);
// This verifies conditionalRun called the Consumer exactly once.
Mockito.verify(itemHandler).accept(Mockito.any(Item.class));
You can verify that your method was called with any lambda expression was called like this:
verify(someClass).myMethodThatExpectsALambda(any())
private fun <T> any(): T {
Mockito.any<T>()
return null as T
}
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