Mocking, Dusk, Pest PHP
<?php
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Queue;
use Illuminate\Support\Facades\Notification;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Storage;
class OrderTest extends TestCase
{
public function test_order_sends_confirmation_email(): void
{
Mail::fake();
$order = Order::factory()->create();
$order->complete();
Mail::assertSent(OrderConfirmation::class, function ($mail) use ($order) {
return $mail->order->id === $order->id;
});
}
public function test_order_dispatches_job(): void
{
Queue::fake();
$order = Order::factory()->create();
ProcessOrder::dispatch($order);
Queue::assertPushed(ProcessOrder::class);
Queue::assertPushedOn('orders', ProcessOrder::class);
}
public function test_user_notified_on_order(): void
{
Notification::fake();
$user = User::factory()->create();
$order = Order::factory()->for($user)->create();
$user->notify(new OrderShipped($order));
Notification::assertSentTo($user, OrderShipped::class);
}
public function test_file_upload(): void
{
Storage::fake('s3');
$file = UploadedFile::fake()->image('photo.jpg');
$response = $this->postJson('/api/upload', [
'photo' => $file,
]);
Storage::disk('s3')->assertExists('photos/' . $file->hashName());
}
}
composer require --dev laravel/dusk
php artisan dusk:install
# Run dusk tests
php artisan dusk
<?php
// tests/Browser/LoginTest.php
namespace Tests\Browser;
use App\Models\User;
use Laravel\Dusk\Browser;
use Tests\DuskTestCase;
class LoginTest extends DuskTestCase
{
public function test_user_can_login(): void
{
$user = User::factory()->create();
$this->browse(function (Browser $browser) use ($user) {
$browser->visit('/login')
->type('email', $user->email)
->type('password', 'password')
->press('Đăng nhập')
->assertPathIs('/dashboard')
->assertSee('Chào mừng');
});
}
public function test_shopping_cart_flow(): void
{
$this->browse(function (Browser $browser) {
$browser->visit('/products')
->click('@add-to-cart-btn')
->waitFor('@cart-count')
->assertSeeIn('@cart-count', '1')
->click('@checkout-btn')
->assertPathIs('/checkout');
});
}
}
<?php
// tests/Feature/PostTest.php
use App\Models\Post;
use App\Models\User;
test('can list posts', function () {
Post::factory()->count(5)->create();
$response = $this->getJson('/api/posts');
$response->assertOk()
->assertJsonCount(5, 'data');
});
test('authenticated user can create post', function () {
$user = User::factory()->create();
$this->actingAs($user)
->postJson('/api/posts', [
'title' => 'Test Post',
'content' => 'Content here',
])
->assertCreated();
expect(Post::count())->toBe(1);
expect(Post::first()->title)->toBe('Test Post');
});
test('guest cannot create post', function () {
$this->postJson('/api/posts', [
'title' => 'Test',
'content' => 'Content',
])->assertUnauthorized();
});
// Dataset testing
dataset('invalid_emails', [
'not-an-email',
'missing@domain',
'@nodomain.com',
]);
test('rejects invalid emails', function (string $email) {
$this->postJson('/api/register', ['email' => $email])
->assertJsonValidationErrors(['email']);
})->with('invalid_emails');
test() và
expect(). Laravel 11 mặc định dùng Pest.