Bird
Raised Fist0
Laravelframework~10 mins

Mocking and faking in Laravel - Step-by-Step Execution

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Concept Flow - Mocking and faking
Start Test
↓
Create Fake/Mock
↓
Inject into Code
↓
Run Code Using Fake/Mock
↓
Verify Behavior or Output
↓
Test Pass/Fail
↓
End
This flow shows how Laravel tests use mocks or fakes to replace real parts, run code, then check results.
Execution Sample
Laravel
<?php
use Illuminate\Support\Facades\Notification;

public function testUserReceivesNotification()
{
    Notification::fake();
    $user = User::factory()->create();
    $user->notify(new WelcomeNotification());
    Notification::assertSentTo($user, WelcomeNotification::class);
}
This test fakes notifications, triggers one, then checks if it was sent to the user.
Execution Table
StepActionEffectState ChangeVerification
1Call Notification::fake()Replaces real notification with fakeNotification facade now uses fakeNo notifications sent yet
2Create user with factoryUser object created in databaseUser exists in DBUser ready for notification
3Call $user->notify(new WelcomeNotification())Notification sent via fakeFake records notification sentNotification recorded but not actually sent
4Call Notification::assertSentTo($user, WelcomeNotification::class)Checks if notification was sent to userNo state changeAssertion passes if notification recorded
5Test endsTest passes if assertion trueTest completeTest result: PASS
💡 Test ends after assertion confirms notification was sent to user
Variable Tracker
VariableStartAfter Step 2After Step 3Final
Notification facadeReal notification systemFake notification system activeFake records notification sentFake notification system active
$userNot createdUser object createdUser object existsUser object exists
Notifications sent001 (WelcomeNotification)1 (WelcomeNotification)
Key Moments - 3 Insights
Why do we call Notification::fake() before sending notifications?
Calling Notification::fake() replaces the real notification system with a fake one that records notifications instead of sending them. This is shown in execution_table step 1 and 3.
Does Notification::assertSentTo() send a notification?
No, assertSentTo() only checks if a notification was recorded as sent by the fake. It does not send anything. See execution_table step 4.
What happens if we don't fake notifications in the test?
Without faking, notifications would actually send, which is not good for tests. Also, assertSentTo() would fail because no fake records exist. This is why step 1 is important.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, what is the state of the Notification facade after step 2?
AIt uses the fake notification system
BIt uses the real notification system
CIt has sent one notification
DIt is uninitialized
💡 Hint
Check the 'State Change' column at step 2 in the execution_table
At which step does the test verify if the notification was sent?
AStep 1
BStep 4
CStep 3
DStep 5
💡 Hint
Look at the 'Verification' column to find when assertion happens
If Notification::fake() was not called, what would happen to the test?
ATest would pass anyway
BNotification::assertSentTo() would record notifications
CNotification would be sent for real and test might fail
DUser would not be created
💡 Hint
Refer to key_moments about why faking is needed before sending notifications
Concept Snapshot
Laravel Mocking and Faking Cheat Sheet:
- Use Notification::fake() to replace real notifications with a fake.
- Run code that triggers notifications.
- Use Notification::assertSentTo() to check if notification was sent.
- Fakes record calls without side effects.
- Always fake before triggering to avoid real actions.
Full Transcript
In Laravel testing, mocking and faking help replace real services with test doubles. For example, Notification::fake() swaps the real notification system with a fake that records notifications instead of sending them. Then, when code triggers notifications, the fake records them. Finally, tests use assertions like Notification::assertSentTo() to verify notifications were sent to the right users. This approach avoids side effects and makes tests reliable. The execution flow starts with faking, then creating data, triggering notifications, asserting, and ending the test. Variables like the Notification facade switch from real to fake, and notifications sent count changes from zero to one. Key points include always faking before sending and understanding that assertions check recorded calls, not send notifications themselves.

Practice

(1/5)
1. What is the main purpose of mocking and faking in Laravel testing?
easy
A. To automatically generate user interfaces
B. To simulate external services without performing real actions
C. To permanently store test data in the database
D. To speed up the application in production

Solution

  1. Step 1: Understand mocking and faking concept

    Mocking and faking are used to imitate external services or actions during tests without actually performing them.
  2. Step 2: Identify the purpose in Laravel testing

    Laravel uses mocking and faking to avoid real side effects like sending emails or making HTTP requests during tests.
  3. Final Answer:

    To simulate external services without performing real actions -> Option B
  4. Quick Check:

    Mocking = simulate services [OK]
Hint: Mocking means faking external actions in tests [OK]
Common Mistakes:
  • Thinking mocking speeds up production
  • Confusing mocking with real data storage
  • Assuming mocking creates UI automatically
2. Which Laravel method correctly fakes sending emails in a test?
easy
A. Mail::fake();
B. Mail::sendFake();
C. Mail::mock();
D. Mail::simulate();

Solution

  1. Step 1: Recall Laravel's mail faking method

    Laravel provides the Mail::fake() method to fake email sending during tests.
  2. Step 2: Check method correctness

    Only Mail::fake() is the correct and existing method; others are invalid or do not exist.
  3. Final Answer:

    Mail::fake(); -> Option A
  4. Quick Check:

    Mail::fake() = correct syntax [OK]
Hint: Use Mail::fake() to fake emails in Laravel tests [OK]
Common Mistakes:
  • Using non-existent methods like Mail::sendFake()
  • Confusing mock() with fake()
  • Forgetting the parentheses ()
3. What will the following Laravel test code output?
use Illuminate\Support\Facades\Http;

Http::fake();

$response = Http::get('https://example.com/api');

return $response->status();
medium
A. null
B. 404
C. 500
D. 200

Solution

  1. Step 1: Understand Http::fake() behavior

    Http::fake() fakes all HTTP requests and returns a default successful response with status 200.
  2. Step 2: Analyze the returned status code

    The $response->status() returns 200 because the fake response simulates success.
  3. Final Answer:

    200 -> Option D
  4. Quick Check:

    Http::fake() returns 200 status [OK]
Hint: Http::fake() returns 200 status by default [OK]
Common Mistakes:
  • Assuming fake returns 404 or error
  • Expecting null instead of response object
  • Confusing Http::fake() with real HTTP call
4. Identify the error in this Laravel test code snippet:
use Illuminate\Support\Facades\Storage;

Storage::fake('local');

Storage::put('file.txt', 'Hello');

$this->assertTrue(Storage::exists('file.txt'));
medium
A. Storage::fake() must be called with 'public' disk, not 'local'
B. Storage::exists() should be Storage::disk('local')->exists()
C. No error, the code is correct
D. Storage::put() cannot be used after Storage::fake()

Solution

  1. Step 1: Understand Storage::fake() usage

    Storage::fake('local') fakes the 'local' disk, which is Laravel's default disk.
  2. Step 2: Check method calls for disk specification

    Storage::put() and Storage::exists() use the default disk ('local'), so they interact with the faked disk correctly. The assertion passes.
  3. Final Answer:

    No error, the code is correct -> Option C
  4. Quick Check:

    Default disk = 'local' [OK]
Hint: Storage:: methods use default disk after Storage::fake('local') [OK]
Common Mistakes:
  • Thinking disk must always be explicitly specified
  • Believing Storage::put() is disallowed after fake
  • Confusing required disk names
5. You want to test that your Laravel app sends exactly one notification to a user without actually sending it. Which approach correctly achieves this?
hard
A. Use Notification::fake() and then assertNotificationSent()
B. Use Notification::send() and check the database for records
C. Use Notification::mock() and assertNothingSent()
D. Use Notification::fake() and then assertNothingSent()

Solution

  1. Step 1: Choose the correct faking method for notifications

    Notification::fake() prevents real notifications from sending and allows assertions.
  2. Step 2: Use the right assertion to check one notification sent

    assertNotificationSent() verifies that a notification was sent exactly once to the user.
  3. Final Answer:

    Use Notification::fake() and then assertNotificationSent() -> Option A
  4. Quick Check:

    Notification::fake() + assertNotificationSent() = test notifications [OK]
Hint: Fake notifications, then assertNotificationSent() to check sends [OK]
Common Mistakes:
  • Using assertNothingSent() when expecting a notification
  • Trying to check notifications via database records
  • Using non-existent Notification::mock() method