Closed ChristianVermeulen closed 1 year ago
The callback of Argument::that
must return a boolean indicating whether the argument matched the expectation. When it returns a falsy value, we consider that this was not a match, and we'll try the next signature being registered.
@stof Ah I see. That fixes it indeed. That was... Unexpected...😅 Thanks for the quick reply!
Note that those assertSame
are a bad idea in that callback (unless you catch their failure exception to return false
), as they would break cases where the callback would not match the argument and another call definition should be used.
@stof
Note that those
assertSame
are a bad idea in that callback (unless you catch their failure exception to returnfalse
), as they would break cases where the callback would not match the argument and another call definition should be used.
In that case I would probably do a type check first and early return false
before doing any assertions so it can move on to the next callback token. If for some reason we do add an extra call without updating the test, either the assertions will fail or the callback's typehinted parameter will break due to the wrong type of object being injected. Either way it will have been caught I guess. :-)
but those callbacks are not meant to throw. Otherwise, you cannot configure a second allow call (as the first candidate call would throw when attempting to match it).
but those callbacks are not meant to throw. Otherwise, you cannot configure a second allow call (as the first candidate call would throw when attempting to match it).
That's exactly what I want... Because if I add something now to my class without updating the test, I want the test to fail so I know I need to update the test for the new code... In which case I will add that second call and provide both with early false
returns so they are skipped when not applicable.
$eventBus
->dispatch(Argument::that(function($event){
if ($event instanceof MemberAdded === false) {
return false;
}
$this->assertSame(IdBuilder::ID, $event->id);
// ...
return true;
}))
->willReturn(new Envelope($eventBus))
->shouldBeCalledOnce()
;
$eventBus
->dispatch(Argument::that(function($event){
if ($event instanceof MemberUpdated === false) {
return false;
}
$this->assertSame(IdBuilder::ID, $event->id);
// ...
return true;
}))
->willReturn(new Envelope($eventBus))
->shouldBeCalledOnce()
Or am I missing something here?
Unexpected calls are already making Prophecy trigger a failure. But your checks based on assertSame
throwing forbid you to have multiple expected calls with MemberUpdated objects for different ids for instance.
I'm writing a test which uses the
Argument::that()
callback and then sets awillReturn
. However, thewillReturn
is somehow ignored. The callback works and is called (validated with avar_dump()
) and when I useArgument::type()
thewillReturn()
does work. So it seems to specifically be in combination with an argument callback.Result (notice the var dump showing up and the stub returning
null
instead of mywillReturn
):But without the callback:
Result: