A Quickie – Dealing with Observers and Testing in Laravel 5.1

If you use Laravel 5.1, you probably heard about model observers. Basically, they just observe a certain model and when a certain action is done (or it is going to be done) it executes a separate logic. It is really a great way to deal with model events, instead of declaring things right in the EventServiceProvider.

Said that, this morning I had some issues while dealing with observers during testing with PHPUnit.

The Laravel documentation says that you can disable event triggering with something like:


class ExampleTest extends TestCase
    public function testUserRegistration()

        // Test user registration code...

(source: http://laravel.com/docs/5.1/testing#mocking-events)

Here’s the bad news: it does not work with observers. Even if you type the $this->withoutEvents(); the observer is loaded and called. Bye bye, isolated testing!

Now, it seems that no one on internet had a similar issue. That’s quite strange because I like observers and I think they are useful, and more elegant than the classic model events declaration.

This is how I solved my problem.

public function testCanSave()
    $this->app->bind(MediaUploaderObserver::class, function(){
        return $this->getMockBuilder(MediaUploaderObserver::class)->disableOriginalConstructor()->getMock();

    // test logic goes here...

By using the $this->app->bind method to create a new binding in the service container, I managed to solve the problem. The closure passed as the second argument returns a mock of the original MediaUploaderObserver class.

Screenshot from 2015-12-08 14:02:34

And that’s all, folks!

  • Damir Miladinov

    Yes, I expected `withoutEvents` to work exactly that way. Funny…
    Have you found a better solution for this? I found that it is possible to detach dispatcher on models and it will just ignore events if you do this: `Model::unsetEventDispatcher();`