تست Repository و Action در Laravel — unit test بدون HTTP
Feature test از HTTP شروع میکند — کامل اما کند. وقتی logic در Action و Repository است، unit test مستقیم روی handle() سریعتر و دقیقتر failure میدهد.
تست Action با mock Repository
use Mockery;
it('creates post via action', function () {
$dto = new CreatePostData('Title', 'title', 'Content');
$user = User::factory()->make(['id' => 1]);
$expected = Post::factory()->make(['title' => 'Title']);
$repo = Mockery::mock(PostRepositoryInterface::class);
$repo->shouldReceive('create')
->once()
->with(Mockery::on(fn ($d) => $d['title'] === 'Title'))
->andReturn($expected);
$action = new CreatePostAction($repo);
$result = $action->handle($dto, $user);
expect($result->title)->toBe('Title');
});
بدون DB — pure unit. Unit test mock.
تست Action با database واقعی
uses(RefreshDatabase::class);
it('persists post', function () {
$user = User::factory()->create();
$dto = new CreatePostData('Test', 'test', 'Body');
$action = app(CreatePostAction::class);
$post = $action->handle($dto, $user);
expect($post)->toBeInstanceOf(Post::class);
$this->assertDatabaseHas('posts', ['slug' => 'test', 'user_id' => $user->id]);
});
integration سبک — Repository واقعی، HTTP نه.
تست Repository
uses(RefreshDatabase::class);
it('finds published posts', function () {
Post::factory()->published()->count(2)->create();
Post::factory()->draft()->create();
$repo = new EloquentPostRepository();
$posts = $repo->published();
expect($posts)->toHaveCount(2);
});
Repository عمدتاً integration test — query درست؟
assert Event
Event::fake([PostCreated::class]);
$action->handle($dto, $user);
Event::assertDispatched(PostCreated::class);
assert Queue
Queue::fake();
// action dispatches job
Queue::assertPushed(SendNewsletterJob::class);
DTO در تست
از DTO در arrange — type-safe setup.
Exception testing
it('throws when slug duplicate', function () {
expect(fn () => $action->handle($duplicateDto, $user))
->toThrow(DuplicateSlugException::class);
});
مرز Unit vs Feature
| Unit (Action mock) | Integration (DB) | Feature (HTTP) |
|---|---|---|
| سریع، logic | query، transaction | route، middleware، JSON |
| mock dependency | Repository واقعی | کل stack |
اشتباهات
- mock همه چیز حتی Eloquent — تست بیمعنی
- Feature test برای هر branch کوچک
- assertion روی implementation نه outcome
جمعبندی
Action unit + Repository integration + Feature critical path = pyramid سالم. Mockery: عمیق. Doubles: Fakes.