Laravel - Mocking - Mocking Objects

When mocking an object that is going to be injected into your application via Laravel's service container, you will need to bind your mocked instance into the container as an instance binding. This will instruct the container to use your mocked instance of the object instead of constructing the object itself:

    
    use App\Service;
    use Mockery;
    use Mockery\MockInterface;
    
    public function test_something_can_be_mocked()
    {
        $this->instance(
            Service::class,
            Mockery::mock(Service::class, function (MockInterface $mock) {
                $mock->shouldReceive('process')->once();
            })
        );
    }
	

In order to make this more convenient, you may use the mock method that is provided by Laravel's base test case class. For example, the following example is equivalent to the example above:

    
    use App\Service;
    use Mockery\MockInterface;
    
    $mock = $this->mock(Service::class, function (MockInterface $mock) {
        $mock->shouldReceive('process')->once();
    });
	

You may use the partialMock method when you only need to mock a few methods of an object. The methods that are not mocked will be executed normally when called:

    
    use App\Service;
    use Mockery\MockInterface;
    
    $mock = $this->partialMock(Service::class, function (MockInterface $mock) {
        $mock->shouldReceive('process')->once();
    });
	

Similarly, if you want to spy on an object, Laravel's base test case class offers a spy method as a convenient wrapper around the Mockery::spy method. Spies are similar to mocks; however, spies record any interaction between the spy and the code being tested, allowing you to make assertions after the code is executed:

    
    use App\Service;
    
    $spy = $this->spy(Service::class);
    
    // ...
    
    $spy->shouldHaveReceived('process');