Giao diện
Mocking
Nguồn gốc: Bản dịch từ Mocking
Giới thiệu (Introduction)
Khi test, bạn có thể muốn "mock" một số phần của ứng dụng để chúng không thực sự thực thi. Ví dụ: test controller dispatch event → mock event listener để không thực thi → chỉ test HTTP response của controller.
Laravel cung cấp helper methods cho mocking events, jobs, facades. Chúng là convenience layer trên Mockery.
Mocking Objects
Mock object inject vào container:
php
use App\Service;
use Mockery;
use Mockery\MockInterface;
test('something can be mocked', function () {
$this->instance(
Service::class,
Mockery::mock(Service::class, function (MockInterface $mock) {
$mock->expects('process');
})
);
});php
use App\Service;
use Mockery;
use Mockery\MockInterface;
public function test_something_can_be_mocked(): void
{
$this->instance(
Service::class,
Mockery::mock(Service::class, function (MockInterface $mock) {
$mock->expects('process');
})
);
}Shortcut tiện lợi với $this->mock():
php
use App\Service;
use Mockery\MockInterface;
$mock = $this->mock(Service::class, function (MockInterface $mock) {
$mock->expects('process');
});Partial Mock
php
$mock = $this->partialMock(Service::class, function (MockInterface $mock) {
$mock->expects('process');
});Method không được mock → thực thi bình thường.
Spies
php
use App\Service;
$spy = $this->spy(Service::class);
// Code thực thi...
$spy->shouldHaveReceived('process');Mocking Facades
Facades có thể mock — ưu điểm lớn so với static methods truyền thống:
php
use Illuminate\Support\Facades\Cache;
test('get index', function () {
Cache::expects('get')
->with('key')
->andReturn('value');
$response = $this->get('/users');
// ...
});php
use Illuminate\Support\Facades\Cache;
use Tests\TestCase;
class UserControllerTest extends TestCase
{
public function test_get_index(): void
{
Cache::expects('get')
->with('key')
->andReturn('value');
$response = $this->get('/users');
// ...
}
}LƯU Ý
Không mock Request facade — thay vào đó dùng get, post trong test. Không mock Config facade — gọi Config::set() trực tiếp.
Facade Spies
php
use Illuminate\Support\Facades\Cache;
Cache::spy();
$response = $this->get('/');
Cache::shouldHaveReceived('put')->once()->with('name', 'Taylor', 10);Tương tác với Time
Laravel cho phép thay đổi thời gian hiện tại trong test:
php
// Du hành đến tương lai
$this->travel(5)->milliseconds();
$this->travel(5)->seconds();
$this->travel(5)->minutes();
$this->travel(5)->hours();
$this->travel(5)->days();
$this->travel(5)->weeks();
$this->travel(5)->years();
// Du hành về quá khứ
$this->travel(-5)->hours();
// Đến thời điểm cụ thể
$this->travelTo(now()->subHours(6));
// Quay về thời gian thực
$this->travelBack();Freeze thời gian:
php
$this->freezeTime();
$this->freezeSecond();