That's what I would expect to work, but it did not, for me:
My test looks like this:
function it_outputs_a_built_product_group_record()
{
Event::fake();
// ...
$command = $this->artisan('debug:productgroup SomeValue testing');
$command->assertExitCode(0);
// ...
$this->assertEventFired(DumpEvent::class, function () { return true; });
}
The always true callback is just to test the basics of this.
However, this fails with "The expected [App\Events\Log\DumpEvent] event was not dispatched.".
What is curious, is that the Event::fake() does do something, since the event is no longer handled normally, so it does capture events. It does not, however, detect it has having been fired.
The name (FQN) of the event is definitely correct.
In Laravel's EventFake, the dispatch() method is called as normal. The event is seen passing in, and $this->shouldFakeEvent($name, $payload) is true for the event, so nothing strange there; the event is stored correctly in the EventFake::$events property. It is, however, not there at the end of the test.
Figured it out: the problem is that this:
$command = $this->artisan('debug:productgroup SomeValue testing');
$command->assertExitCode(0);
does NOT have the same effect as this:
$this->artisan('debug:productgroup SomeValue testing')->assertExitCode(0);
With the first approach, the pending command is NOT fired until the test method ends; with the last approach, the command runs immediately. Probably a destructor trick.
Pretty obscure and easy to miss!