Mocking

    When testing Laravel applications, you may wish to "mock" certain aspects of your application so they are not actually executed during a given test. For example, when testing a controller that dispatches an event, you may wish to mock the event listeners so they are not actually executed during the test. This allows you to only test the controller's HTTP response without worrying about the execution of the event listeners, since the event listeners can be tested in their own test case.

    Laravel provides helpers for mocking events, jobs, and facades out of the box. These helpers primarily provide a convenience layer over Mockery so you do not have to manually make complicated Mockery method calls. Of course, you are free to use Mockery or PHPUnit to create your own mocks or spies.

    Bus Fake

    As an alternative to mocking, you may use the facade's fake method to prevent jobs from being dispatched. When using fakes, assertions are made after the code under test is executed:

    1. <?php
    2. namespace Tests\Feature;
    3. use Tests\TestCase;
    4. use App\Events\OrderShipped;
    5. use App\Events\OrderFailedToShip;
    6. use Illuminate\Support\Facades\Event;
    7. use Illuminate\Foundation\Testing\WithoutMiddleware;
    8. use Illuminate\Foundation\Testing\DatabaseMigrations;
    9. use Illuminate\Foundation\Testing\DatabaseTransactions;
    10. class ExampleTest extends TestCase
    11. {
    12. /**
    13. * Test order shipping.
    14. */
    15. public function testOrderShipping()
    16. {
    17. Event::fake();
    18. // Perform order shipping...
    19. Event::assertDispatched(OrderShipped::class, function ($e) use ($order) {
    20. return $e->order->id === $order->id;
    21. });
    22. Event::assertNotDispatched(OrderFailedToShip::class);
    23. }

    Mail Fake

    You may use the Mail facade's fake method to prevent mail from being sent. You may then assert that mailables were sent to users and even inspect the data they received. When using fakes, assertions are made after the code under test is executed:

    You may use the Notification facade's fake method to prevent notifications from being sent. You may then assert that notifications were sent to users and even inspect the data they received. When using fakes, assertions are made after the code under test is executed:

    1. <?php
    2. namespace Tests\Feature;
    3. use Tests\TestCase;
    4. use App\Notifications\OrderShipped;
    5. use Illuminate\Support\Facades\Notification;
    6. use Illuminate\Foundation\Testing\WithoutMiddleware;
    7. use Illuminate\Foundation\Testing\DatabaseMigrations;
    8. class ExampleTest extends TestCase
    9. {
    10. public function testOrderShipping()
    11. {
    12. Notification::fake();
    13. // Perform order shipping...
    14. Notification::assertSentTo(
    15. $user,
    16. OrderShipped::class,
    17. function ($notification, $channels) use ($order) {
    18. return $notification->order->id === $order->id;
    19. }
    20. );
    21. // Assert a notification was sent to the given users...
    22. Notification::assertSentTo(
    23. [$user], OrderShipped::class
    24. );
    25. // Assert a notification was not sent...
    26. Notification::assertNotSentTo(
    27. [$user], AnotherNotification::class
    28. );
    29. }
    30. }

    Queue Fake

    The Storage facade's fake method allows you to easily generate a fake disk that, combined with the file generation utilities of the UploadedFile class, greatly simplifies the testing of file uploads. For example:

    1. <?php
    2. namespace Tests\Feature;
    3. use Tests\TestCase;
    4. use Illuminate\Support\Facades\Storage;
    5. use Illuminate\Foundation\Testing\WithoutMiddleware;
    6. use Illuminate\Foundation\Testing\DatabaseMigrations;
    7. use Illuminate\Foundation\Testing\DatabaseTransactions;
    8. class ExampleTest extends TestCase
    9. {
    10. {
    11. Storage::fake('avatars');
    12. $response = $this->json('POST', '/avatar', [
    13. 'avatar' => UploadedFile::fake()->image('avatar.jpg')
    14. ]);
    15. // Assert the file was stored...
    16. Storage::disk('avatars')->assertExists('avatar.jpg');
    17. // Assert a file does not exist...
    18. Storage::disk('avatars')->assertMissing('missing.jpg');
    19. }
    20. }

    Facades

    Unlike traditional static method calls, facades may be mocked. This provides a great advantage over traditional static methods and grants you the same testability you would have if you were using dependency injection. When testing, you may often want to mock a call to a Laravel facade in one of your controllers. For example, consider the following controller action:

    1. <?php
    2. namespace Tests\Feature;
    3. use Tests\TestCase;
    4. use Illuminate\Support\Facades\Cache;
    5. use Illuminate\Foundation\Testing\WithoutMiddleware;
    6. use Illuminate\Foundation\Testing\DatabaseMigrations;
    7. use Illuminate\Foundation\Testing\DatabaseTransactions;
    8. class UserControllerTest extends TestCase
    9. {
    10. public function testGetIndex()
    11. {
    12. Cache::shouldReceive('get')
    13. ->once()
    14. ->with('key')
    15. ->andReturn('value');
    16. $response = $this->get('/users');
    17. // ...
    18. }

    {note} You should not mock the Request facade. Instead, pass the input you desire into the HTTP helper methods such as get and post when running your test. Likewise, instead of mocking the facade, simply call the Config::set method in your tests.