Laravel: Test HTTP

Các khóa học qua video:
Python SQL Server PHP C# Lập trình C Java HTML5-CSS3-JavaScript
Học trên YouTube <76K/tháng. Đăng ký Hội viên
Viết nhanh hơn - Học tốt hơn
Giải phóng thời gian, khai phóng năng lực

Mục lục bài viết

Giới thiệu

Laravel cung cấp một API rất tuyệt vời để tạo các request HTTP tới ứng dụng và kiểm tra output. Ví dụ sau đây định nghĩa một test:

<?php

namespace Tests\Feature;

use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;

class ExampleTest extends TestCase
{
    /**
     * A basic test example.
     *
     * @return void
     */
    public function testBasicTest()
    {
        $response = $this->get('/');

        $response->assertStatus(200);
    }
}

Phương thức get method tạo một request GET vào ứng dụng, còn phương thức assertStatus xác nhận response cần có mã trạng thái HTTP đã cho. Ngoài xác nhận đơn giản này thì Laravel còn chứa một loạt các xác nhận khác để test các header, content, cấu trúc JSON, ...

Tùy chỉnh Request Headers

Ta có thể sử dụng phương thức withHeaders để tùy chỉnh các header của request trước khi gửi nó tới ứng dụng. Điều này sẽ cho phép ta thêm bất kỳ header tùy chỉnh nào ta muốn cho request:

<?php

class ExampleTest extends TestCase
{
    /**
     * A basic functional test example.
     *
     * @return void
     */
    public function testBasicExample()
    {
        $response = $this->withHeaders([
            'X-Header' => 'Value',
        ])->json('POST', '/user', ['name' => 'Sally']);

        $response
            ->assertStatus(201)
            ->assertJson([
                'created' => true,
            ]);
    }
}
Middleware CSRF sẽ tự động được disable khi chạy test.

Session / Authentication

Laravel cung cấp một số helper để làm việc với session khi test HTTP. Trước tiên ta cần thiết lập data session tới một mảng đã cho bằng việc sử dụng phương thức withSession. Việc này rất hữu dụng khi tải session với data trước khi tạo request tới ứng dụng:

<?php

class ExampleTest extends TestCase
{
    public function testApplication()
    {
        $response = $this->withSession(['foo' => 'bar'])
                         ->get('/');
    }
}

Thường thì session dùng để duy trì trạng thái cho người dùng đã được xác thực. Phương thức hỗ trợ actingAs cung cấp một cách khá đơn giản để xác thực người dùng. Ví dụ, ta có thể sử dụng model factory để tạo và xác thực người dùng như sau:

<?php

use App\User;

class ExampleTest extends TestCase
{
    public function testApplication()
    {
        $user = factory(User::class)->create();

        $response = $this->actingAs($user)
                         ->withSession(['foo' => 'bar'])
                         ->get('/');
    }
}

Ta cũng có thể chỉ định guard nào cần được dùng để xác thực người dùng bằng cách truyền tên của guard là tham số thứ 2 của phương thức actingAs:

$this->actingAs($user, 'api')

Test JSON API

Laravel cũng cung cấp một số trình hỗ trợ để test JSON API và các response của chúng. Ví dụ các phương thức jsongetpostputpatch, và delete có thể được dùng để tạo requests tới các HTTP. Ta cũng có thể dễ dàng truyền dữ liệu và các header tới các phương thức này. Để bắt đầu thì ta hay viết một test để tạo một request POST tới /user và xác nhận dữ liệu dự kiến được trả về:

<?php

class ExampleTest extends TestCase
{
    /**
     * A basic functional test example.
     *
     * @return void
     */
    public function testBasicExample()
    {
        $response = $this->json('POST', '/user', ['name' => 'Sally']);

        $response
            ->assertStatus(201)
            ->assertJson([
                'created' => true,
            ]);
    }
}
Phương thức assertJson sẽ chuyển response thành một mảng và sử dụng PHPUnit::assertArraySubset để xác minh mảng đã cho là có sẵn trong response JSON được trả vè bằng ứng dụng. Cho nên, nếu có các thuộc tính khác trong response JSON thì test trên sẽ vẫn hoàn tất miễn là có đoạn đã cho.

Xác nhận đúng là JSON

Nếu ta muốn xác nhận rằng mảng đã cho chính xác là một JSON được trả về bởi ứng dụng thì ta cần sử dụng phương thức assertExactJson:

<?php

class ExampleTest extends TestCase
{
    /**
     * A basic functional test example.
     *
     * @return void
     */
    public function testBasicExample()
    {
        $response = $this->json('POST', '/user', ['name' => 'Sally']);

        $response
            ->assertStatus(201)
            ->assertExactJson([
                'created' => true,
            ]);
    }
}

Test File upload

Class Illuminate\Http\UploadedFile cung cấp một phương thức fake có thể dùng để tạo các file giả hoặc ảnh để test. Khi kết hợp với phương thức fake của facade Storage sẽ giúp ta đơn giản hóa việc test file upload. Ví dụ, ta có thể kết hợp 2 đặc điểm này để dễ dàng test một form upload avatar:

<?php

namespace Tests\Feature;

use Tests\TestCase;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;

class ExampleTest extends TestCase
{
    public function testAvatarUpload()
    {
        Storage::fake('avatars');

        $file = UploadedFile::fake()->image('avatar.jpg');

        $response = $this->json('POST', '/avatar', [
            'avatar' => $file,
        ]);

        // Assert the file was stored...
        Storage::disk('avatars')->assertExists($file->hashName());

        // Assert a file does not exist...
        Storage::disk('avatars')->assertMissing('missing.jpg');
    }
}

Tùy chỉnh file giả

Khi tạo các file sử dụng phương thức fake thì ta có thể chỉ định chiều rộng, chiều cao và size của anh để test tốt hơn các quy tắc xác thực của ta:

UploadedFile::fake()->image('avatar.jpg', $width, $height)->size(100);

Cùng với việc tạo ảnh thì ta có thể tạo các file với kiểu bất kỳ sử dung phương thức create:

UploadedFile::fake()->create('document.pdf', $sizeInKilobytes);

Các Assertion sẵn có

Assetion Response

Laravel cung cấp một số phương thức assertion tùy chỉnh cho việc test PHPUnit. Các assertion này có thể được truy cập trên các response được trả về từ các phương thức test jsongetpostput, và delete:

assertCookie

Xác nhận response có chứa cookie đã cho:

$response->assertCookie($cookieName, $value = null);

assertCookieExpired

Xác nhận response có chứa cookie đã cho và nó đã hết hạn:

$response->assertCookieExpired($cookieName);

assertCookieNotExpired

Xác nhận response có chứa cookie đã cho và nó chưa hết hạn:

$response->assertCookieNotExpired($cookieName);

assertCookieMissing

Xác nhận response không chứa cookie đã cho:

$response->assertCookieMissing($cookieName);

assertDontSee

Xác nhận rằng chuỗi đã cho không nằm trong response:

$response->assertDontSee($value);

assertDontSeeText

Xác nhận rằng chuỗi đã cho không nằm trong response text:

$response->assertDontSeeText($value);

assertExactJson

Xác nhận rằng response chứa một tương thích chính xác của data JSON đã cho:

$response->assertExactJson(array $data);

assertForbidden

Xác nhận rằng response cho một mã trạng thái bị cấm:

$response->assertForbidden();

assertHeader

Xác nhận rằng header đã cho có trong response:

$response->assertHeader($headerName, $value = null);

assertHeaderMissing

Xác nhận rằng header đã cho không có trong response:

$response->assertHeaderMissing($headerName);

assertJson

Xác nhận rằng response có chứa data JSON đã cho:

$response->assertJson(array $data);

assertJsonCount

Xác nhận rằng response JSON có một mảng với số lượng mục dữ kiến tại key đã cho:

$response->assertJsonCount($count, $key = null);

assertJsonFragment

Xác nhận rằng response chưa đoạn JSON đã cho:

$response->assertJsonFragment(array $data);

assertJsonMissing

Xác nhận rằng response không chứa đoạn JSON đã cho:

$response->assertJsonMissing(array $data);

assertJsonMissingExact

Xác nhận rằng response không chứa đoạn JSON chính xác:

$response->assertJsonMissingExact(array $data);

assertJsonStructure

Xác nhận rằng response có cấu trúc JSON đã cho:

$response->assertJsonStructure(array $structure);

assertJsonValidationErrors

Xác nhận rằng response có các lỗi xác thực JSON đã cho cho các key đã cho:

$response->assertJsonValidationErrors($keys);

assertLocation

Xác nhận rằng response có giá trị URL đã cho trong header Location:

$response->assertLocation($uri);

assertNotFound

Xác nhận rằng response có một mã trạng thái không tìm thấy:

$response->assertNotFound();

assertOk

Xác nhận rằng response có một mã trạng thái 200:

$response->assertOk();

assertPlainCookie

Xác nhận rằng response chứa cookie đã cho (không được mã hóa):

$response->assertPlainCookie($cookieName, $value = null);

assertRedirect

Xác nhận rằng response là một request tới URI đã cho:

$response->assertRedirect($uri);

assertSee

Xác nhận rằng chuỗi đã cho nằm trong response:

$response->assertSee($value);

assertSeeInOrder

Xác nhận rằng các chuỗi đã cho nằm trong response:

$response->assertSeeInOrder(array $values);

assertSeeText

Xác nhận rằng chuỗi đã cho nằm trong response text:

$response->assertSeeText($value);

assertSeeTextInOrder

Xác nhận rằng các chuỗi đã cho nằm trong response text:

$response->assertSeeTextInOrder(array $values);

assertSessionHas

Xác nhận rằng session chứa phần dữ liệu đã cho:

$response->assertSessionHas($key, $value = null);

assertSessionHasAll

Xác nhận rằng session có một danh sách các giá trị đã cho:

$response->assertSessionHasAll(array $data);

assertSessionHasErrors

Xác nhận rằng session chứa một lỗi ứng với trường đã cho:

$response->assertSessionHasErrors(array $keys, $format = null, $errorBag = 'default');

assertSessionHasErrorsIn

Xác nhận rằng session có các lỗi đã cho:

$response->assertSessionHasErrorsIn($errorBag, $keys = [], $format = null);

assertSessionHasNoErrors

Xác nhận rằng session không có lỗi:

$response->assertSessionHasNoErrors();

assertSessionMissing

Xác nhận rằng session không chứa key đã cho:

$response->assertSessionMissing($key);

assertStatus

Xác nhận rằng response có mã lệnh đã cho:

$response->assertStatus($code);

assertSuccessful

Xác nhận rằng response có một mã trạng thái thành công:

$response->assertSuccessful();

assertViewHas

Xác nhận rằng response view được cho một phần của dữ liệu:

$response->assertViewHas($key, $value = null);

assertViewHasAll

Xác nhận rằng response view có một danh sách dữ liệu đã cho:

$response->assertViewHasAll(array $data);

assertViewIs

Xác nhận rằng view đã cho được trả về bởi route:

$response->assertViewIs($value);

assertViewMissing

Xác nhận rằng response view đang thiếu một phần dữ liệu ràng buộc:

$response->assertViewMissing($key);

Xác nhận xác thực

Laravel cũng cung cấp các xác nhận liên quan đến việc xác thực cho các test PHPUnit:

Phương thức Mô tả
$this->assertAuthenticated($guard = null); Xác nhận rằng người dùng đã được xác thực.
$this->assertGuest($guard = null); Xác nhận rằng người dùng không được xác thực.
$this->assertAuthenticatedAs($user, $guard = null); Xác nhận rằng người dùng đã cho được xác thực.
$this->assertCredentials(array $credentials, $guard = null); Xác nhận rằng các thông tin đã cho là hợp lệ.
$this->assertInvalidCredentials(array $credentials, $guard = null); Xác nhận rằng các thông tin đã cho không hợp lệ.
» Tiếp: Test Console
« Trước: Bắt đầu
Các khóa học qua video:
Python SQL Server PHP C# Lập trình C Java HTML5-CSS3-JavaScript
Học trên YouTube <76K/tháng. Đăng ký Hội viên
Viết nhanh hơn - Học tốt hơn
Giải phóng thời gian, khai phóng năng lực
Copied !!!