jijoel's avatar
Level 10

How do we turn event handling back on for test after ->withoutEvents?

I have a class that emits an event which ultimately sends an email. For most of the tests for that class, I don't want an email sent, so this is my setUp function:

public function setUp()
{
    parent::setUp();

    $this->withoutEvents();
}

In one specific test, I would like to enable event handling again, to make sure the e-mail is submitted. I've tried this:

/** @test */
public function it_sends_a_welcome_email_when_new_user_registers()
{
    $this->app->instance('events', new Dispatcher);
    Mail::fake();

    $mock = factory(User::class)->make()->toArray();
    $mock['password'] = 'something';
    $mock['password_confirmation'] = 'something';

    $this->json('post', '/register', $mock)
        ->assertStatus(200);

    Mail::assertSent(WelcomeEmail::class);
}

It didn't work. Laravel doesn't include a ->withEvents function, either. If I disable the call to ->withoutEvents(), the tests run slower, and I receive several e-mail messages. The Mail fake doesn't work, though, unless I disable the call to app->instance, also.

I can split the test into another file, one with events and one without, but that seems clumsy. Is there a better way?

0 likes
1 reply
bobbybouwmann's avatar

well it's basically replacing the implementation in the container to do that. So you can either replace it back with the correct implementation which should work just fine

Code: https://github.com/laravel/framework/blob/892b2cef309ea86cc110f7c153e81474eb1b2a35/src/Illuminate/Foundation/Testing/Concerns/MocksApplicationServices.php#L92

An another alternative would be to use a seperate test class that doesn't have this in the setUp method or moving the withoutEvents to the tests that actually need it!

Please or to participate in this conversation.