Bird
Raised Fist0
Laravelframework~15 mins

Mocking and faking in Laravel - Deep Dive

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
Overview - Mocking and faking
What is it?
Mocking and faking are techniques used in testing Laravel applications to simulate parts of the system. Mocking creates fake versions of objects or methods to control their behavior during tests. Faking replaces real implementations with simple stand-ins to isolate the code being tested. These help test code without relying on real external services or complex dependencies.
Why it matters
Without mocking and faking, tests would depend on real databases, APIs, or services, making them slow, unreliable, and hard to run often. This would slow down development and increase bugs in production. Mocking and faking let developers test code quickly and safely, catching errors early and improving confidence in their applications.
Where it fits
Before learning mocking and faking, you should understand basic Laravel testing and PHP unit testing concepts. After mastering mocking and faking, you can explore advanced testing topics like integration tests, test-driven development, and continuous integration pipelines.
Mental Model
Core Idea
Mocking and faking let you replace real parts of your Laravel app with controlled stand-ins to test code in isolation.
Think of it like...
It's like practicing a play with stand-in actors who follow a script exactly, so you can focus on your own lines without worrying about others improvising.
┌─────────────┐       ┌─────────────┐
│ Real Object │──────▶│ Real Behavior│
└─────────────┘       └─────────────┘
       ▲                     ▲
       │                     │
┌─────────────┐       ┌─────────────┐
│ Mock/Fake   │──────▶│ Controlled  │
│ Object      │       │ Behavior    │
└─────────────┘       └─────────────┘
Build-Up - 7 Steps
1
FoundationUnderstanding Laravel Testing Basics
🤔
Concept: Learn how Laravel runs tests and what testing means in this framework.
Laravel uses PHPUnit for testing. Tests are classes that check if your code works as expected. You write test methods that run code and assert results. Laravel provides helpers to make testing easier, like creating fake data or calling routes.
Result
You can run tests that verify your Laravel app's behavior automatically.
Knowing how Laravel testing works is essential before adding complexity like mocks or fakes.
2
FoundationWhat Are Mocks and Fakes?
🤔
Concept: Introduce the difference between mocks and fakes in testing.
A mock is a fake object that you program to expect certain calls and respond in specific ways. A fake is a simpler replacement that behaves like the real thing but is easier to control. Laravel provides tools to create both for testing.
Result
You understand the basic idea of replacing real parts with controlled stand-ins.
Distinguishing mocks and fakes helps you choose the right tool for your test scenario.
3
IntermediateUsing Laravel's Mockery for Mocks
🤔Before reading on: do you think mocks can verify how many times a method was called or just replace its output? Commit to your answer.
Concept: Learn how to create mocks with Mockery in Laravel to control and verify method calls.
Mockery is a PHP library integrated with Laravel for mocking. You create a mock object, define expected method calls and return values, then inject it into your code. After running the test, Mockery checks if the expectations were met.
Result
Tests can check not only outputs but also how code interacts with dependencies.
Understanding that mocks verify interactions helps catch subtle bugs in how components communicate.
4
IntermediateFaking Laravel Services with Built-in Helpers
🤔Before reading on: do you think fakes simulate behavior fully or just provide simple stand-ins? Commit to your answer.
Concept: Use Laravel's built-in fakes to replace services like mail, queues, or events during tests.
Laravel offers methods like Mail::fake(), Queue::fake(), and Event::fake() to replace real services with simple versions that record calls. This lets you test if your code triggers these services without actually sending emails or dispatching jobs.
Result
You can test side effects safely and quickly without external dependencies.
Knowing Laravel's fakes exist saves time and avoids writing complex mocks for common services.
5
IntermediateInjecting Mocks and Fakes in Laravel Tests
🤔
Concept: Learn how to provide mocks or fakes to your Laravel classes using dependency injection.
Laravel supports dependency injection, so you can pass mocks or fakes into constructors or methods. In tests, you create the mock/fake and bind it in the service container or pass it directly. This replaces the real dependency during the test run.
Result
Your tests isolate the code under test by controlling its dependencies precisely.
Mastering injection of mocks/fakes is key to writing clean, maintainable tests.
6
AdvancedCombining Multiple Mocks and Fakes in Complex Tests
🤔Before reading on: do you think multiple mocks can be used together seamlessly or cause conflicts? Commit to your answer.
Concept: Learn how to coordinate several mocks and fakes in one test to simulate complex scenarios.
In real apps, code often depends on many services. You can create multiple mocks and fakes, set expectations on each, and inject them properly. Laravel's container helps manage these dependencies. Careful setup avoids conflicts and ensures tests remain clear.
Result
You can test complex interactions without relying on real services or databases.
Knowing how to manage multiple mocks/fakes prevents fragile tests and improves reliability.
7
ExpertUnderstanding Mocking Internals and Pitfalls in Laravel
🤔Before reading on: do you think mocks always behave exactly like real objects? Commit to your answer.
Concept: Explore how Laravel and Mockery create mocks behind the scenes and common mistakes to avoid.
Mockery uses PHP's dynamic features to create proxy objects that mimic real classes. However, mocks don't run real code, so logic inside methods is skipped. Over-mocking can hide bugs or create false positives. Also, forgetting to verify expectations can let errors slip by.
Result
You gain a deep understanding of mock behavior and how to write robust tests.
Understanding mock internals helps avoid common testing traps and write meaningful tests.
Under the Hood
Laravel uses Mockery, which dynamically creates proxy objects at runtime. These proxies intercept method calls, check them against expectations, and return programmed responses. Laravel's fakes replace service bindings in the container with simple classes that record calls but do not execute real logic. This isolation allows tests to run quickly and predictably.
Why designed this way?
Mocking and faking were designed to solve the problem of slow, unreliable tests that depend on external systems. Dynamic proxies allow flexible control without changing production code. Laravel's container makes swapping implementations easy, enabling seamless testing without modifying app logic.
┌───────────────┐       ┌───────────────┐
│ Test Code     │──────▶│ Mockery Proxy │
│ (calls method)│       │ (intercepts)  │
└───────────────┘       └───────────────┘
          │                      │
          ▼                      ▼
┌───────────────┐       ┌───────────────┐
│ Expectation   │       │ Return Value  │
│ Check         │       │ or Exception  │
└───────────────┘       └───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Do mocks run the real code inside the methods they replace? Commit to yes or no.
Common Belief:Mocks run the actual code inside the methods they mock, just like the real objects.
Tap to reveal reality
Reality:Mocks do NOT run the real method code; they only simulate responses based on expectations.
Why it matters:Assuming mocks run real code can lead to tests that miss bugs or behave differently than production.
Quick: Is faking the same as mocking, just with a different name? Commit to yes or no.
Common Belief:Faking and mocking are the same thing; the terms can be used interchangeably.
Tap to reveal reality
Reality:Fakes are simpler stand-ins that provide basic behavior, while mocks verify interactions and expectations.
Why it matters:Confusing the two can cause misuse of tools, making tests either too fragile or too weak.
Quick: Can you rely on mocks to test integration with real external services? Commit to yes or no.
Common Belief:Mocks are good enough to test how your app integrates with real external services.
Tap to reveal reality
Reality:Mocks isolate code and do not test real external service behavior; integration tests are needed for that.
Why it matters:Relying only on mocks can miss real-world issues like network failures or API changes.
Quick: Do you need to verify mock expectations manually after tests? Commit to yes or no.
Common Belief:Mock expectations are automatically verified without extra steps in Laravel tests.
Tap to reveal reality
Reality:You must explicitly verify or let the testing framework check mock expectations to catch failures.
Why it matters:Skipping verification can let tests pass even if expected calls never happened.
Expert Zone
1
Mocks can cause brittle tests if overused; balancing between mocks and real objects improves test resilience.
2
Laravel's service container allows swapping implementations globally, but local injection can avoid side effects in parallel tests.
3
Mockery supports partial mocks that call real methods selectively, useful for testing complex classes without full stubbing.
When NOT to use
Avoid mocking or faking when testing full integration or end-to-end flows; use real services or dedicated test environments instead. For simple data transformations, direct testing without mocks is often clearer.
Production Patterns
In production Laravel apps, mocks and fakes are used extensively in unit tests to isolate logic. Fakes are preferred for Laravel services like mail and queues. Complex domain logic uses partial mocks to test behavior without full stubbing. Continuous integration pipelines run these tests automatically to catch regressions early.
Connections
Dependency Injection
Mocks and fakes rely on dependency injection to replace real objects with test doubles.
Understanding dependency injection clarifies how mocks are swapped in tests without changing production code.
Test-Driven Development (TDD)
Mocking and faking enable writing tests first by isolating code dependencies.
Knowing mocking helps implement TDD effectively by allowing incremental testing of small units.
Theatre Rehearsal
Both involve stand-ins to practice and verify behavior before the real performance.
Recognizing this connection highlights the purpose of mocks as controlled practice partners.
Common Pitfalls
#1Writing tests that mock too many internal details, making tests fragile and hard to maintain.
Wrong approach:mock->shouldReceive('methodA')->once(); mock->shouldReceive('methodB')->once(); // Test breaks if internal calls change
Correct approach:mock->shouldReceive('publicMethod')->once(); // Test focuses on public behavior, not internals
Root cause:Misunderstanding that tests should verify behavior, not implementation details.
#2Forgetting to call Mail::fake() before sending emails in tests, causing real emails to be sent.
Wrong approach:public function testEmailSent() { // No Mail::fake() Mail::send(...); // Test runs but sends real email }
Correct approach:public function testEmailSent() { Mail::fake(); Mail::send(...); Mail::assertSent(...); }
Root cause:Not knowing Laravel's fakes must be activated explicitly to prevent real actions.
#3Assuming mocks automatically verify expectations without calling Mockery::close() or using PHPUnit integration.
Wrong approach:public function testSomething() { $mock = Mockery::mock(...); $mock->shouldReceive('foo')->once(); // No verification step }
Correct approach:public function tearDown(): void { Mockery::close(); } public function testSomething() { $mock = Mockery::mock(...); $mock->shouldReceive('foo')->once(); }
Root cause:Not understanding that mock expectations require explicit verification.
Key Takeaways
Mocking and faking let you replace real parts of your Laravel app with controlled stand-ins to test code in isolation.
Laravel provides powerful tools like Mockery and built-in fakes for common services to simplify testing.
Using mocks helps verify how your code interacts with dependencies, while fakes simulate behavior simply.
Proper injection of mocks and fakes is essential to keep tests clean and maintainable.
Overusing mocks or misunderstanding their behavior can lead to fragile or misleading tests.

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