php - Event listener not dispatched while testing
I fire an event in my controller that dispatches a listener which sends an email. My code works fine in production. However I'm currently writing a testcase for it (using a full http request), but the event listener doesn't handle the fired event (which is fired).
How can I activate the listener in my testcase? Am I missing something? The code works well, when I test it by hand.
I'm using Laravel 5.4 with PHP 7.1 and PHPUnit.
I have not used something likeEvent::fake();
Here is a minified version of my code:
class OrderController extends Controller
{
public function store(Request $request): JsonResponse
{
$order = new Order($request->all());
$order->store();
event(new OrderStored($order));
// no problem here
return response()->json(['id' => $order->id()]);
}
}
-
class OrderStored
{
private $order;
public function __construct(Order $order)
{
$this->order = $order;
// this place is reachable
}
public function getOrder(): Order
{
return $this->order;
}
}
-
class SendOrderStoredEmail
{
private $mailer;
public function __construct(Mailer $mailer)
{
// this place is not reachable in my tests
$this->mailer = $mailer;
}
public function handle(OrderStored $event): void
{
$this->mailer->send(new OrderStoredMail($event->getOrder()));
}
}
And finally my EventServiceProvider:
class EventServiceProvider extends BaseEventServiceProvider
{
protected $listen = [
OrderStored::class => [SendOrderStoredEmail::class],
];
}
Answer
Solution:
Mail::fake();
injects an intance of MailFake into my listener, so the type hinting fails. Using the contract ofIlluminate\Contracts\Mail\Mailer
solves the problem.