0
0
LaravelHow-ToBeginner · 3 min read

How to Mock in Laravel Test: Simple Guide with Examples

In Laravel tests, you can mock classes or interfaces using $this->mock() or Mockery to replace real implementations with fake ones. This helps isolate the code under test by controlling dependencies and their behavior during testing.
📐

Syntax

Laravel provides a simple way to mock classes or interfaces in tests using $this->mock(). You pass the class or interface name, then define expectations on the mock object.

Example parts:

  • $this->mock(ClassName::class): creates a mock instance.
  • ->shouldReceive('methodName'): defines which method to fake.
  • ->andReturn(value): specifies the return value when the method is called.
php
<?php
public function test_example()
{
    $mock = $this->mock(SomeService::class);
    $mock->shouldReceive('doSomething')
         ->once()
         ->andReturn('mocked result');

    // Your test code here
}
💻

Example

This example shows how to mock a service class in a Laravel test to control its method output and test a controller that depends on it.

php
<?php
namespace Tests\Feature;

use Tests\TestCase;
use App\Services\PaymentGateway;
use Illuminate\Foundation\Testing\RefreshDatabase;

class PaymentControllerTest extends TestCase
{
    public function test_payment_process_uses_mocked_gateway()
    {
        $this->mock(PaymentGateway::class, function ($mock) {
            $mock->shouldReceive('charge')
                 ->once()
                 ->with(100)
                 ->andReturn(true);
        });

        $response = $this->post('/payment', ['amount' => 100]);

        $response->assertStatus(200);
        $response->assertSee('Payment successful');
    }
}
Output
HTTP 200 OK with text 'Payment successful' in response body
⚠️

Common Pitfalls

Common mistakes when mocking in Laravel tests include:

  • Not binding the mock in the service container, so the real class is used instead.
  • Forgetting to specify method expectations, causing tests to pass without actually testing behavior.
  • Using mocks for integration tests where real implementations are needed.

Always ensure your mock matches the interface or class methods used by your code.

php
<?php
// Wrong: Mock created but not bound, real class used
$mock = Mockery::mock(SomeService::class);

// Right: Use $this->mock() to bind mock in container
$this->mock(SomeService::class, function ($mock) {
    $mock->shouldReceive('method')->andReturn('value');
});
📊

Quick Reference

MethodDescription
$this->mock(Class::class)Creates and binds a mock instance in the container
->shouldReceive('method')Defines a method to mock on the object
->once()Expects the method to be called exactly once
->andReturn(value)Specifies the return value for the mocked method
Mockery::mock()Creates a mock but does not bind automatically (use carefully)

Key Takeaways

Use $this->mock() in Laravel tests to create and bind mocks easily.
Define method expectations with shouldReceive() and specify return values.
Always bind mocks in the service container to replace real implementations.
Avoid mocking in integration tests where real behavior is needed.
Check that mocked methods match those used by your code to avoid silent test failures.