Your ways can also verify that is invoked exactly once by replacing boolean[]
with int[]
, for example:
final int[] calls = new int[1];
instance.conditionalRun(item -> {
calls[0]++;
item.foo();
});
Assert.assertEquals(1, calls[0]);
Note: using mockito is more complicated since you called item.foo()
later.
Edit
After thinking I found that your test testing more than one behavior that result in the test is complicated, for more details you can see Why should unit tests test only one thing?, and the test can be separated at least as below since I see the intention of your test code:
@Test
void runOnceWhenConditionIsSatisfied() throws Throwable {
final int[] calls = new int[1];
instance.conditionalRun(item -> calls[0]++);
Assert.assertEquals(1, calls[0]);
}
@Test
void anotherTest() throws Throwable {
instance.conditionalRun(item -> {
item.foo();
});
//... testing your SUT here
}
AND then you can happy to replace State Verification with Behavior Verification by using mockito as below.
@Test
void runOnceWhenConditionIsSatisfied() throws Throwable {
Consumer<T> it= Mockito.mock(Consumer.class);
// ^--- T is the type of item
instance.conditionalRun(it);
Mockito.verify(it,Mockito.only()).accept(Mockito.any());
// using any to ignore matching the parameters ---^
}