翻譯進度
47.28% 已翻譯
更新時間:
2024年6月30日 上午8:27:00 [世界標準時間]
翻譯人員:
幫我們翻譯此頁

HTTP 測試

簡介

Laravel 提供了一個語義化的 API,這個 API 可以建立連到我們專案的 HTTP Request(請求),並讓我們能加以檢查 Response(回覆)。舉例來說,我們來看看下面定義的這個 Feature Test:

1<?php
2 
3test('the application returns a successful response', function () {
4 $response = $this->get('/');
5 
6 $response->assertStatus(200);
7});
1<?php
2 
3test('the application returns a successful response', function () {
4 $response = $this->get('/');
5 
6 $response->assertStatus(200);
7});
1<?php
2 
3namespace Tests\Feature;
4 
5use Tests\TestCase;
6 
7class ExampleTest extends TestCase
8{
9 /**
10 * A basic test example.
11 */
12 public function test_the_application_returns_a_successful_response(): void
13 {
14 $response = $this->get('/');
15 
16 $response->assertStatus(200);
17 }
18}
1<?php
2 
3namespace Tests\Feature;
4 
5use Tests\TestCase;
6 
7class ExampleTest extends TestCase
8{
9 /**
10 * A basic test example.
11 */
12 public function test_the_application_returns_a_successful_response(): void
13 {
14 $response = $this->get('/');
15 
16 $response->assertStatus(200);
17 }
18}

get 方法會建立連到專案的 GET Request,而 assertStatus 方法則會判斷回傳的 Response 是否為給定的 HTTP 狀態碼。出了這種簡單的 Assertion(判斷提示) 外,Laravel 也提供了各種不同的 Assertion,可用來檢查 Response 的 Header(標頭)、內容、JSON 結構…等。

建立 Request

若要建立連到專案的 Request,可以在測試中叫用 getpostputpatchdelete 方法。這些方法不會真的建立「真正的」HTTP Request,而是在程式內部模擬一段網路連線。

這些測試 Request 方法不是回傳 Illuminate\Http\Response 實體,而是回傳 Illuminate\Testing\TestResponse 的實體。TestResponse 實體提供了各種實用的 Assertion,可讓我們檢查專案的 Response:

1<?php
2 
3test('basic request', function () {
4 $response = $this->get('/');
5 
6 $response->assertStatus(200);
7});
1<?php
2 
3test('basic request', function () {
4 $response = $this->get('/');
5 
6 $response->assertStatus(200);
7});
1<?php
2 
3namespace Tests\Feature;
4 
5use Tests\TestCase;
6 
7class ExampleTest extends TestCase
8{
9 /**
10 * A basic test example.
11 */
12 public function test_a_basic_request(): void
13 {
14 $response = $this->get('/');
15 
16 $response->assertStatus(200);
17 }
18}
1<?php
2 
3namespace Tests\Feature;
4 
5use Tests\TestCase;
6 
7class ExampleTest extends TestCase
8{
9 /**
10 * A basic test example.
11 */
12 public function test_a_basic_request(): void
13 {
14 $response = $this->get('/');
15 
16 $response->assertStatus(200);
17 }
18}

一般來說,每個測試都應只向專案建立一個 Request。若在單一測試方法內建立多個 Request,可能會發生未預期的行為。

lightbulb

為了方便期間,在執行測試期間會自動禁用 CSRF Middleware。

自訂 Request 的 Header

可使用 withHeaders 方法來在 Request 傳送到專案前先自訂 Request 的 Header。使用這個方法,我們就可以自行加上任何需要的自定 Request:

1<?php
2 
3test('interacting with headers', function () {
4 $response = $this->withHeaders([
5 'X-Header' => 'Value',
6 ])->post('/user', ['name' => 'Sally']);
7 
8 $response->assertStatus(201);
9});
1<?php
2 
3test('interacting with headers', function () {
4 $response = $this->withHeaders([
5 'X-Header' => 'Value',
6 ])->post('/user', ['name' => 'Sally']);
7 
8 $response->assertStatus(201);
9});
1<?php
2 
3namespace Tests\Feature;
4 
5use Tests\TestCase;
6 
7class ExampleTest extends TestCase
8{
9 /**
10 * A basic functional test example.
11 */
12 public function test_interacting_with_headers(): void
13 {
14 $response = $this->withHeaders([
15 'X-Header' => 'Value',
16 ])->post('/user', ['name' => 'Sally']);
17 
18 $response->assertStatus(201);
19 }
20}
1<?php
2 
3namespace Tests\Feature;
4 
5use Tests\TestCase;
6 
7class ExampleTest extends TestCase
8{
9 /**
10 * A basic functional test example.
11 */
12 public function test_interacting_with_headers(): void
13 {
14 $response = $this->withHeaders([
15 'X-Header' => 'Value',
16 ])->post('/user', ['name' => 'Sally']);
17 
18 $response->assertStatus(201);
19 }
20}

Cookie

我們可以使用 withCookiewithCookies 方法來在建立 Request 前設定 Cookie 值。withCookie 方法有兩個引數:Cookie 名稱與 Cookie 值。withCookies 方法則接受一組名稱/值配對的陣列:

1<?php
2 
3test('interacting with cookies', function () {
4 $response = $this->withCookie('color', 'blue')->get('/');
5 
6 $response = $this->withCookies([
7 'color' => 'blue',
8 'name' => 'Taylor',
9 ])->get('/');
10 
11 //
12});
1<?php
2 
3test('interacting with cookies', function () {
4 $response = $this->withCookie('color', 'blue')->get('/');
5 
6 $response = $this->withCookies([
7 'color' => 'blue',
8 'name' => 'Taylor',
9 ])->get('/');
10 
11 //
12});
1<?php
2 
3namespace Tests\Feature;
4 
5use Tests\TestCase;
6 
7class ExampleTest extends TestCase
8{
9 public function test_interacting_with_cookies(): void
10 {
11 $response = $this->withCookie('color', 'blue')->get('/');
12 
13 $response = $this->withCookies([
14 'color' => 'blue',
15 'name' => 'Taylor',
16 ])->get('/');
17 
18 //
19 }
20}
1<?php
2 
3namespace Tests\Feature;
4 
5use Tests\TestCase;
6 
7class ExampleTest extends TestCase
8{
9 public function test_interacting_with_cookies(): void
10 {
11 $response = $this->withCookie('color', 'blue')->get('/');
12 
13 $response = $this->withCookies([
14 'color' => 'blue',
15 'name' => 'Taylor',
16 ])->get('/');
17 
18 //
19 }
20}

Session 與身份驗證

Laravel 提供了各種在 HTTP 測試期間處理 Session 的輔助函式。首先,我們可以使用給定 withSession 方法來以給定的陣列設定 Session 資料。若要在向專案傳送 Request 前先在 Session 內載入資料,就適合使用這個方法:

1<?php
2 
3test('interacting with the session', function () {
4 $response = $this->withSession(['banned' => false])->get('/');
5 
6 //
7});
1<?php
2 
3test('interacting with the session', function () {
4 $response = $this->withSession(['banned' => false])->get('/');
5 
6 //
7});
1<?php
2 
3namespace Tests\Feature;
4 
5use Tests\TestCase;
6 
7class ExampleTest extends TestCase
8{
9 public function test_interacting_with_the_session(): void
10 {
11 $response = $this->withSession(['banned' => false])->get('/');
12 
13 //
14 }
15}
1<?php
2 
3namespace Tests\Feature;
4 
5use Tests\TestCase;
6 
7class ExampleTest extends TestCase
8{
9 public function test_interacting_with_the_session(): void
10 {
11 $response = $this->withSession(['banned' => false])->get('/');
12 
13 //
14 }
15}

由於 Laravel 的 Session 通常是用來保存目前登入使用者的狀態,因此,也有一個 actingAs 輔助函式方法,可更簡單地讓我們將給定的使用者登入為目前使用者。舉例來說,我們可以使用 Model Factory 來產生並登入使用者:

1<?php
2 
3use App\Models\User;
4 
5test('an action that requires authentication', function () {
6 $user = User::factory()->create();
7 
8 $response = $this->actingAs($user)
9 ->withSession(['banned' => false])
10 ->get('/');
11 
12 //
13});
1<?php
2 
3use App\Models\User;
4 
5test('an action that requires authentication', function () {
6 $user = User::factory()->create();
7 
8 $response = $this->actingAs($user)
9 ->withSession(['banned' => false])
10 ->get('/');
11 
12 //
13});
1<?php
2 
3namespace Tests\Feature;
4 
5use App\Models\User;
6use Tests\TestCase;
7 
8class ExampleTest extends TestCase
9{
10 public function test_an_action_that_requires_authentication(): void
11 {
12 $user = User::factory()->create();
13 
14 $response = $this->actingAs($user)
15 ->withSession(['banned' => false])
16 ->get('/');
17 
18 //
19 }
20}
1<?php
2 
3namespace Tests\Feature;
4 
5use App\Models\User;
6use Tests\TestCase;
7 
8class ExampleTest extends TestCase
9{
10 public function test_an_action_that_requires_authentication(): void
11 {
12 $user = User::factory()->create();
13 
14 $response = $this->actingAs($user)
15 ->withSession(['banned' => false])
16 ->get('/');
17 
18 //
19 }
20}

只要在 actingAs 方法上傳入第二個引數,就可以指定要使用哪個 Guard 來登入給定的使用者。傳給 actingAs 方法的 Guard 會在該測試期間變成預設的 Guard:

1$this->actingAs($user, 'web')
1$this->actingAs($user, 'web')

為 Response 進行偵錯

向專案建立測試 Request 後,可使用 dumpdumpHeadersdumpSession 方法來取得 Response 的內容或對其偵錯:

1<?php
2 
3test('basic test', function () {
4 $response = $this->get('/');
5 
6 $response->dumpHeaders();
7 
8 $response->dumpSession();
9 
10 $response->dump();
11});
1<?php
2 
3test('basic test', function () {
4 $response = $this->get('/');
5 
6 $response->dumpHeaders();
7 
8 $response->dumpSession();
9 
10 $response->dump();
11});
1<?php
2 
3namespace Tests\Feature;
4 
5use Tests\TestCase;
6 
7class ExampleTest extends TestCase
8{
9 /**
10 * A basic test example.
11 */
12 public function test_basic_test(): void
13 {
14 $response = $this->get('/');
15 
16 $response->dumpHeaders();
17 
18 $response->dumpSession();
19 
20 $response->dump();
21 }
22}
1<?php
2 
3namespace Tests\Feature;
4 
5use Tests\TestCase;
6 
7class ExampleTest extends TestCase
8{
9 /**
10 * A basic test example.
11 */
12 public function test_basic_test(): void
13 {
14 $response = $this->get('/');
15 
16 $response->dumpHeaders();
17 
18 $response->dumpSession();
19 
20 $response->dump();
21 }
22}

或者,我們可以使用 ddddHeadersddSession 方法來將該 Response 相關的資料傾印出來,並停止執行:

1<?php
2 
3test('basic test', function () {
4 $response = $this->get('/');
5 
6 $response->ddHeaders();
7 
8 $response->ddSession();
9 
10 $response->dd();
11});
1<?php
2 
3test('basic test', function () {
4 $response = $this->get('/');
5 
6 $response->ddHeaders();
7 
8 $response->ddSession();
9 
10 $response->dd();
11});
1<?php
2 
3namespace Tests\Feature;
4 
5use Tests\TestCase;
6 
7class ExampleTest extends TestCase
8{
9 /**
10 * A basic test example.
11 */
12 public function test_basic_test(): void
13 {
14 $response = $this->get('/');
15 
16 $response->ddHeaders();
17 
18 $response->ddSession();
19 
20 $response->dd();
21 }
22}
1<?php
2 
3namespace Tests\Feature;
4 
5use Tests\TestCase;
6 
7class ExampleTest extends TestCase
8{
9 /**
10 * A basic test example.
11 */
12 public function test_basic_test(): void
13 {
14 $response = $this->get('/');
15 
16 $response->ddHeaders();
17 
18 $response->ddSession();
19 
20 $response->dd();
21 }
22}

處理 Exception

Sometimes you may need to test that your application is throwing a specific exception. To accomplish this, you may "fake" the exception handler via the Exceptions facade. Once the exception handler has been faked, you may utilize the assertReported and assertNotReported methods to make assertions against exceptions that were thrown during the request:

1<?php
2 
3use App\Exceptions\InvalidOrderException;
4use Illuminate\Support\Facades\Exceptions;
5 
6test('exception is thrown', function () {
7 Exceptions::fake();
8 
9 $response = $this->get('/order/1');
10 
11 // Assert an exception was thrown...
12 Exceptions::assertReported(InvalidOrderException::class);
13 
14 // Assert against the exception...
15 Exceptions::assertReported(function (InvalidOrderException $e) {
16 return $e->getMessage() === 'The order was invalid.';
17 });
18});
1<?php
2 
3use App\Exceptions\InvalidOrderException;
4use Illuminate\Support\Facades\Exceptions;
5 
6test('exception is thrown', function () {
7 Exceptions::fake();
8 
9 $response = $this->get('/order/1');
10 
11 // Assert an exception was thrown...
12 Exceptions::assertReported(InvalidOrderException::class);
13 
14 // Assert against the exception...
15 Exceptions::assertReported(function (InvalidOrderException $e) {
16 return $e->getMessage() === 'The order was invalid.';
17 });
18});
1<?php
2 
3namespace Tests\Feature;
4 
5use App\Exceptions\InvalidOrderException;
6use Illuminate\Support\Facades\Exceptions;
7use Tests\TestCase;
8 
9class ExampleTest extends TestCase
10{
11 /**
12 * A basic test example.
13 */
14 public function test_exception_is_thrown(): void
15 {
16 Exceptions::fake();
17 
18 $response = $this->get('/');
19 
20 // Assert an exception was thrown...
21 Exceptions::assertReported(InvalidOrderException::class);
22 
23 // Assert against the exception...
24 Exceptions::assertReported(function (InvalidOrderException $e) {
25 return $e->getMessage() === 'The order was invalid.';
26 });
27 }
28}
1<?php
2 
3namespace Tests\Feature;
4 
5use App\Exceptions\InvalidOrderException;
6use Illuminate\Support\Facades\Exceptions;
7use Tests\TestCase;
8 
9class ExampleTest extends TestCase
10{
11 /**
12 * A basic test example.
13 */
14 public function test_exception_is_thrown(): void
15 {
16 Exceptions::fake();
17 
18 $response = $this->get('/');
19 
20 // Assert an exception was thrown...
21 Exceptions::assertReported(InvalidOrderException::class);
22 
23 // Assert against the exception...
24 Exceptions::assertReported(function (InvalidOrderException $e) {
25 return $e->getMessage() === 'The order was invalid.';
26 });
27 }
28}

The assertNotReported and assertNothingReported methods may be used to assert that a given exception was not thrown during the request or that no exceptions were thrown:

1Exceptions::assertNotReported(InvalidOrderException::class);
2 
3Exceptions::assertNothingReported();
1Exceptions::assertNotReported(InvalidOrderException::class);
2 
3Exceptions::assertNothingReported();

You may totally disable exception handling for a given request by invoking the withoutExceptionHandling method before making your request:

1$response = $this->withoutExceptionHandling()->get('/');
1$response = $this->withoutExceptionHandling()->get('/');

此外,若想確保專案中未使用到 PHP 或其他專案使用套件中宣告 Deprecated(已過時) 的功能,我們可以在建立 Request 前叫用 withoutDeprecationHandling 方法。停用 Deprecation Handling 後,Deprecation Warning(警告) 會被轉換為 Exception,並導致測試執行失敗:

1$response = $this->withoutDeprecationHandling()->get('/');
1$response = $this->withoutDeprecationHandling()->get('/');

assertThrows 方法可用來判斷給定的閉包是否有擲回特定型別的 Exception:

1$this->assertThrows(
2 fn () => (new ProcessOrder)->execute(),
3 OrderInvalid::class
4);
1$this->assertThrows(
2 fn () => (new ProcessOrder)->execute(),
3 OrderInvalid::class
4);

If you would like to inspect and make assertions against the exception that is thrown, you may provide a closure as the second argument to the assertThrows method:

1$this->assertThrows(
2 fn () => (new ProcessOrder)->execute(),
3 fn (OrderInvalid $e) => $e->orderId() === 123;
4);
1$this->assertThrows(
2 fn () => (new ProcessOrder)->execute(),
3 fn (OrderInvalid $e) => $e->orderId() === 123;
4);

測試 JSON API

Laravel 中也提供了數種可用來測試 JSON API 與起 Response 的輔助函式。舉例來說,jsongetJsonpostJsonputJsonpatchJsondeleteJsonoptionsJson 等方法可用來以各種 HTTP Verb(指令動詞) 來建立 JSON Request。我們也可以輕鬆地將資料與 Header 傳給這些方法。若要開始測試 JSON API,我們先來撰寫一個建立連到 /api/userPOST Request,並撰寫預期回傳 JSON 資料的 Assertion:

1<?php
2 
3test('making an api request', function () {
4 $response = $this->postJson('/api/user', ['name' => 'Sally']);
5 
6 $response
7 ->assertStatus(201)
8 ->assertJson([
9 'created' => true,
10 ]);
11});
1<?php
2 
3test('making an api request', function () {
4 $response = $this->postJson('/api/user', ['name' => 'Sally']);
5 
6 $response
7 ->assertStatus(201)
8 ->assertJson([
9 'created' => true,
10 ]);
11});
1<?php
2 
3namespace Tests\Feature;
4 
5use Tests\TestCase;
6 
7class ExampleTest extends TestCase
8{
9 /**
10 * A basic functional test example.
11 */
12 public function test_making_an_api_request(): void
13 {
14 $response = $this->postJson('/api/user', ['name' => 'Sally']);
15 
16 $response
17 ->assertStatus(201)
18 ->assertJson([
19 'created' => true,
20 ]);
21 }
22}
1<?php
2 
3namespace Tests\Feature;
4 
5use Tests\TestCase;
6 
7class ExampleTest extends TestCase
8{
9 /**
10 * A basic functional test example.
11 */
12 public function test_making_an_api_request(): void
13 {
14 $response = $this->postJson('/api/user', ['name' => 'Sally']);
15 
16 $response
17 ->assertStatus(201)
18 ->assertJson([
19 'created' => true,
20 ]);
21 }
22}

此外,在 Response 上,我們可以用陣列變數的形式來存取 JSON Response 的資料。這麼一來我們就能方便地檢查 JSON Response 中回傳的各個值:

1expect($response['created'])->toBeTrue();
1expect($response['created'])->toBeTrue();
1$this->assertTrue($response['created']);
1$this->assertTrue($response['created']);
lightbulb

The assertJson method converts the response to an array to verify that the given array exists within the JSON response returned by the application. So, if there are other properties in the JSON response, this test will still pass as long as the given fragment is present.

判斷 JSON 是否完全符合

剛才也提到過,assertJson 方法可用來判斷給定的部分 JSON 是否有包含在 JSON Response 中。若想檢查給定的陣列是否與專案回傳的 JSON 完全符合,請使用 assertExactJson 方法:

1<?php
2 
3test('asserting an exact json match', function () {
4 $response = $this->postJson('/user', ['name' => 'Sally']);
5 
6 $response
7 ->assertStatus(201)
8 ->assertExactJson([
9 'created' => true,
10 ]);
11});
1<?php
2 
3test('asserting an exact json match', function () {
4 $response = $this->postJson('/user', ['name' => 'Sally']);
5 
6 $response
7 ->assertStatus(201)
8 ->assertExactJson([
9 'created' => true,
10 ]);
11});
1<?php
2 
3namespace Tests\Feature;
4 
5use Tests\TestCase;
6 
7class ExampleTest extends TestCase
8{
9 /**
10 * A basic functional test example.
11 */
12 public function test_asserting_an_exact_json_match(): void
13 {
14 $response = $this->postJson('/user', ['name' => 'Sally']);
15 
16 $response
17 ->assertStatus(201)
18 ->assertExactJson([
19 'created' => true,
20 ]);
21 }
22}
1<?php
2 
3namespace Tests\Feature;
4 
5use Tests\TestCase;
6 
7class ExampleTest extends TestCase
8{
9 /**
10 * A basic functional test example.
11 */
12 public function test_asserting_an_exact_json_match(): void
13 {
14 $response = $this->postJson('/user', ['name' => 'Sally']);
15 
16 $response
17 ->assertStatus(201)
18 ->assertExactJson([
19 'created' => true,
20 ]);
21 }
22}

Asserting on JSON Paths

若想檢查 JSON Response 中,特定路徑上是否有包含給定資料,可使用 assertJsonPath 方法:

1<?php
2 
3test('asserting a json path value', function () {
4 $response = $this->postJson('/user', ['name' => 'Sally']);
5 
6 $response
7 ->assertStatus(201)
8 ->assertJsonPath('team.owner.name', 'Darian');
9});
1<?php
2 
3test('asserting a json path value', function () {
4 $response = $this->postJson('/user', ['name' => 'Sally']);
5 
6 $response
7 ->assertStatus(201)
8 ->assertJsonPath('team.owner.name', 'Darian');
9});
1<?php
2 
3namespace Tests\Feature;
4 
5use Tests\TestCase;
6 
7class ExampleTest extends TestCase
8{
9 /**
10 * A basic functional test example.
11 */
12 public function test_asserting_a_json_paths_value(): void
13 {
14 $response = $this->postJson('/user', ['name' => 'Sally']);
15 
16 $response
17 ->assertStatus(201)
18 ->assertJsonPath('team.owner.name', 'Darian');
19 }
20}
1<?php
2 
3namespace Tests\Feature;
4 
5use Tests\TestCase;
6 
7class ExampleTest extends TestCase
8{
9 /**
10 * A basic functional test example.
11 */
12 public function test_asserting_a_json_paths_value(): void
13 {
14 $response = $this->postJson('/user', ['name' => 'Sally']);
15 
16 $response
17 ->assertStatus(201)
18 ->assertJsonPath('team.owner.name', 'Darian');
19 }
20}

assertJsonPath 方法也接受一個閉包,該閉包可用於動態判斷該 Assertion 是否應設為通過:

1$response->assertJsonPath('team.owner.name', fn (string $name) => strlen($name) >= 3);
1$response->assertJsonPath('team.owner.name', fn (string $name) => strlen($name) >= 3);

Fluent JSON 測試

Laravel 也提供了另一種較好看、語義化的方法來讓我們測試專案的 JSON Response。若要用這種方法來測試 JSON Response,只需要傳入一個閉包給 assertJson。在叫用這個閉包時,該閉包會收到一個 Illuminate\Testing\Fluent\AssertableJson 實體。AssertableJson 可用來對專案回傳的 JSON 做 Assertion。where 方法可用來對 JSON 中特定屬性做 Assertion。而 missing 方法可用來判斷 JSON 中是否不含特定屬性:

1use Illuminate\Testing\Fluent\AssertableJson;
2 
3test('fluent json', function () {
4 $response = $this->getJson('/users/1');
5 
6 $response
7 ->assertJson(fn (AssertableJson $json) =>
8 $json->where('id', 1)
9 ->where('name', 'Victoria Faith')
10 ->where('email', fn (string $email) => str($email)->is('[email protected]'))
11 ->whereNot('status', 'pending')
12 ->missing('password')
13 ->etc()
14 );
15});
1use Illuminate\Testing\Fluent\AssertableJson;
2 
3test('fluent json', function () {
4 $response = $this->getJson('/users/1');
5 
6 $response
7 ->assertJson(fn (AssertableJson $json) =>
8 $json->where('id', 1)
9 ->where('name', 'Victoria Faith')
10 ->where('email', fn (string $email) => str($email)->is('[email protected]'))
11 ->whereNot('status', 'pending')
12 ->missing('password')
13 ->etc()
14 );
15});
1use Illuminate\Testing\Fluent\AssertableJson;
2 
3/**
4 * A basic functional test example.
5 */
6public function test_fluent_json(): void
7{
8 $response = $this->getJson('/users/1');
9 
10 $response
11 ->assertJson(fn (AssertableJson $json) =>
12 $json->where('id', 1)
13 ->where('name', 'Victoria Faith')
14 ->where('email', fn (string $email) => str($email)->is('[email protected]'))
15 ->whereNot('status', 'pending')
16 ->missing('password')
17 ->etc()
18 );
19}
1use Illuminate\Testing\Fluent\AssertableJson;
2 
3/**
4 * A basic functional test example.
5 */
6public function test_fluent_json(): void
7{
8 $response = $this->getJson('/users/1');
9 
10 $response
11 ->assertJson(fn (AssertableJson $json) =>
12 $json->where('id', 1)
13 ->where('name', 'Victoria Faith')
14 ->where('email', fn (string $email) => str($email)->is('[email protected]'))
15 ->whereNot('status', 'pending')
16 ->missing('password')
17 ->etc()
18 );
19}

Understanding the etc Method

在上述的範例中,讀者可能有注意到我們在 Assersion 串列的最後面叫用了 etc 方法。叫用該方法可讓 Laravel 知道在 JSON 物件中可能還有其他屬性。在沒有使用 etc 方法的情況下,若 JSON 物件中還有其他屬性存在,而我們未對這些屬性進行 Assersion 時,測試會執行失敗。

這種在沒有呼叫 etc 方法的情況下會使測試失敗的行為,是為了避免讓我們在 JSON Response 中不小心暴露出機敏資訊,所以才強制我們要針對所有屬性做 Assersion,或是使用 etc 方法來顯式允許其他額外的屬性。

不過,也請注意,若在 Assertion 中未串聯呼叫 etc 方法,是無法確保 JSON 物件中沒有被加入巢狀陣列。etc 方法只能確定在與呼叫 etc 方法相同的巢狀層級下沒有其他額外的屬性。

判斷屬性存在/不存在

若要判斷某個屬性存在或不存在,可使用 hasmissing 方法:

1$response->assertJson(fn (AssertableJson $json) =>
2 $json->has('data')
3 ->missing('message')
4);
1$response->assertJson(fn (AssertableJson $json) =>
2 $json->has('data')
3 ->missing('message')
4);

此外,使用 hasAllmissingAll 方法,就可以同時針對多個屬性判斷存在或不存在:

1$response->assertJson(fn (AssertableJson $json) =>
2 $json->hasAll(['status', 'data'])
3 ->missingAll(['message', 'code'])
4);
1$response->assertJson(fn (AssertableJson $json) =>
2 $json->hasAll(['status', 'data'])
3 ->missingAll(['message', 'code'])
4);

我們可以使用 hasAny 方法來判斷給定屬性列表中是否至少有一個屬性存在:

1$response->assertJson(fn (AssertableJson $json) =>
2 $json->has('status')
3 ->hasAny('data', 'message', 'code')
4);
1$response->assertJson(fn (AssertableJson $json) =>
2 $json->has('status')
3 ->hasAny('data', 'message', 'code')
4);

判斷 JSON Collection

通常來說,在 Route 中回傳的 Json Response 會包含多個項目,如多位使用者:

1Route::get('/users', function () {
2 return User::all();
3});
1Route::get('/users', function () {
2 return User::all();
3});

在這些情況下,我們可以使用 Fluent JSON 物件的 has 方法來針對該 Response 中的使用者進行 Assertion。舉例來說,我們來判斷 JSON Response 中是否有包含三位使用者。接著,我們再使用 first 方法來對該 Collection 中的使用者做 Assertion。first 方法接受一個閉包,該閉包會收到另一個可 Assert 的 JSON 字串,我們可以使用這個 JSON 字串來針對該 JSON Collection 中的第一個物件進行 Assertion:

1$response
2 ->assertJson(fn (AssertableJson $json) =>
3 $json->has(3)
4 ->first(fn (AssertableJson $json) =>
5 $json->where('id', 1)
6 ->where('name', 'Victoria Faith')
7 ->where('email', fn (string $email) => str($email)->is('[email protected]'))
8 ->missing('password')
9 ->etc()
10 )
11 );
1$response
2 ->assertJson(fn (AssertableJson $json) =>
3 $json->has(3)
4 ->first(fn (AssertableJson $json) =>
5 $json->where('id', 1)
6 ->where('name', 'Victoria Faith')
7 ->where('email', fn (string $email) => str($email)->is('[email protected]'))
8 ->missing('password')
9 ->etc()
10 )
11 );

限定範圍的 JSON Collection Assertion

有時候,Route 可能會回傳被指派為命名索引鍵的 JSON Collection:

1Route::get('/users', function () {
2 return [
3 'meta' => [...],
4 'users' => User::all(),
5 ];
6})
1Route::get('/users', function () {
2 return [
3 'meta' => [...],
4 'users' => User::all(),
5 ];
6})

在測試這類 Route 時,可以使用 has 方法來判斷該 Collection 中的項目數。此外,也可以使用 has 方法來在一連串的 Assertion 間限制判斷的範圍:

1$response
2 ->assertJson(fn (AssertableJson $json) =>
3 $json->has('meta')
4 ->has('users', 3)
5 ->has('users.0', fn (AssertableJson $json) =>
6 $json->where('id', 1)
7 ->where('name', 'Victoria Faith')
8 ->where('email', fn (string $email) => str($email)->is('[email protected]'))
9 ->missing('password')
10 ->etc()
11 )
12 );
1$response
2 ->assertJson(fn (AssertableJson $json) =>
3 $json->has('meta')
4 ->has('users', 3)
5 ->has('users.0', fn (AssertableJson $json) =>
6 $json->where('id', 1)
7 ->where('name', 'Victoria Faith')
8 ->where('email', fn (string $email) => str($email)->is('[email protected]'))
9 ->missing('password')
10 ->etc()
11 )
12 );

不過,除了一次對 users Collection 呼叫兩次 has 方法以外,我們也可以只呼叫一次,並提供一個閉包作為該方法的第三個引數。傳入閉包時,Laravel 會自動叫用該閉包,並將作用範圍限定在該 Collection 的第一個項目:

1$response
2 ->assertJson(fn (AssertableJson $json) =>
3 $json->has('meta')
4 ->has('users', 3, fn (AssertableJson $json) =>
5 $json->where('id', 1)
6 ->where('name', 'Victoria Faith')
7 ->where('email', fn (string $email) => str($email)->is('[email protected]'))
8 ->missing('password')
9 ->etc()
10 )
11 );
1$response
2 ->assertJson(fn (AssertableJson $json) =>
3 $json->has('meta')
4 ->has('users', 3, fn (AssertableJson $json) =>
5 $json->where('id', 1)
6 ->where('name', 'Victoria Faith')
7 ->where('email', fn (string $email) => str($email)->is('[email protected]'))
8 ->missing('password')
9 ->etc()
10 )
11 );

判斷 JSON 型別

我們可能會想檢查 JSON Response 中的某些屬性是否為特定的型別。Illuminate\Testing\Fluent\AssertableJson 類別中,提供了 whereTypewhereAllType 方法可讓我們檢查 JSON 屬性中的型別:

1$response->assertJson(fn (AssertableJson $json) =>
2 $json->whereType('id', 'integer')
3 ->whereAllType([
4 'users.0.name' => 'string',
5 'meta' => 'array'
6 ])
7);
1$response->assertJson(fn (AssertableJson $json) =>
2 $json->whereType('id', 'integer')
3 ->whereAllType([
4 'users.0.name' => 'string',
5 'meta' => 'array'
6 ])
7);

我們也可以使用 | 字元來指定多個型別,或者,也可以傳入一組型別陣列作為 whereType 的第二個引數。若 Response 值符合任意列出的型別,則該 Assertion 會執行成功:

1$response->assertJson(fn (AssertableJson $json) =>
2 $json->whereType('name', 'string|null')
3 ->whereType('id', ['string', 'integer'])
4);
1$response->assertJson(fn (AssertableJson $json) =>
2 $json->whereType('name', 'string|null')
3 ->whereType('id', ['string', 'integer'])
4);

whereTypewhereAllType 方法可支援下列型別: stringintegerdoublebooleanarraynull

測試檔案上傳

Illuminate\Http\UploadedFile 類別提供了一個 fake 方法,可用來產生用於測試的假檔案或圖片。只要將 UploadedFilefake 方法與 Storage Facade 的 fake 方法一起使用,我們就能大幅簡化測試檔案上傳的過程。舉例來說,我們可以將這兩個功能搭配使用,來測試某個上傳使用者大頭照的表單:

1<?php
2 
3use Illuminate\Http\UploadedFile;
4use Illuminate\Support\Facades\Storage;
5 
6test('avatars can be uploaded', function () {
7 Storage::fake('avatars');
8 
9 $file = UploadedFile::fake()->image('avatar.jpg');
10 
11 $response = $this->post('/avatar', [
12 'avatar' => $file,
13 ]);
14 
15 Storage::disk('avatars')->assertExists($file->hashName());
16});
1<?php
2 
3use Illuminate\Http\UploadedFile;
4use Illuminate\Support\Facades\Storage;
5 
6test('avatars can be uploaded', function () {
7 Storage::fake('avatars');
8 
9 $file = UploadedFile::fake()->image('avatar.jpg');
10 
11 $response = $this->post('/avatar', [
12 'avatar' => $file,
13 ]);
14 
15 Storage::disk('avatars')->assertExists($file->hashName());
16});
1<?php
2 
3namespace Tests\Feature;
4 
5use Illuminate\Http\UploadedFile;
6use Illuminate\Support\Facades\Storage;
7use Tests\TestCase;
8 
9class ExampleTest extends TestCase
10{
11 public function test_avatars_can_be_uploaded(): void
12 {
13 Storage::fake('avatars');
14 
15 $file = UploadedFile::fake()->image('avatar.jpg');
16 
17 $response = $this->post('/avatar', [
18 'avatar' => $file,
19 ]);
20 
21 Storage::disk('avatars')->assertExists($file->hashName());
22 }
23}
1<?php
2 
3namespace Tests\Feature;
4 
5use Illuminate\Http\UploadedFile;
6use Illuminate\Support\Facades\Storage;
7use Tests\TestCase;
8 
9class ExampleTest extends TestCase
10{
11 public function test_avatars_can_be_uploaded(): void
12 {
13 Storage::fake('avatars');
14 
15 $file = UploadedFile::fake()->image('avatar.jpg');
16 
17 $response = $this->post('/avatar', [
18 'avatar' => $file,
19 ]);
20 
21 Storage::disk('avatars')->assertExists($file->hashName());
22 }
23}

若想檢查給定的檔案是否不存在,可使用 Storage Facade 的 assertMissing 方法:

1Storage::fake('avatars');
2 
3// ...
4 
5Storage::disk('avatars')->assertMissing('missing.jpg');
1Storage::fake('avatars');
2 
3// ...
4 
5Storage::disk('avatars')->assertMissing('missing.jpg');

自訂 Fake 檔案

在使用 UploadedFile 類別的 fake 方法來建立檔案時,我們可以指定圖片的長寬與檔案大小 (單位為 kB),以更好地測試程式中的表單驗證規則:

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

除了建立圖片外,還可以使用 create 方法來建立任何其他類型的檔案:

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

若有需要,可傳入 $mimeType 引數,以明顯定義 File 要回傳的 MIME 型別:

1UploadedFile::fake()->create(
2 'document.pdf', $sizeInKilobytes, 'application/pdf'
3);
1UploadedFile::fake()->create(
2 'document.pdf', $sizeInKilobytes, 'application/pdf'
3);

測試 View

在 Laravel 中,我們也可以在不模擬 HTTP Request 的情況轉譯 View。若要在不模擬 HTTP Request 的情況下轉譯 View,我們可以在測試中呼叫 view 方法。view 方法的參數為 View 的名稱,以及一組可選的資料陣列。該方法會回傳 Illuminate\Testing\TestView 的實體,使用 TestView,我們就能方便地針對 View 的內容進行 Assertion:

1<?php
2 
3test('a welcome view can be rendered', function () {
4 $view = $this->view('welcome', ['name' => 'Taylor']);
5 
6 $view->assertSee('Taylor');
7});
1<?php
2 
3test('a welcome view can be rendered', function () {
4 $view = $this->view('welcome', ['name' => 'Taylor']);
5 
6 $view->assertSee('Taylor');
7});
1<?php
2 
3namespace Tests\Feature;
4 
5use Tests\TestCase;
6 
7class ExampleTest extends TestCase
8{
9 public function test_a_welcome_view_can_be_rendered(): void
10 {
11 $view = $this->view('welcome', ['name' => 'Taylor']);
12 
13 $view->assertSee('Taylor');
14 }
15}
1<?php
2 
3namespace Tests\Feature;
4 
5use Tests\TestCase;
6 
7class ExampleTest extends TestCase
8{
9 public function test_a_welcome_view_can_be_rendered(): void
10 {
11 $view = $this->view('welcome', ['name' => 'Taylor']);
12 
13 $view->assertSee('Taylor');
14 }
15}

TestView 類別還提供了下列 Assertion 方法:assertSeeassertSeeInOrderassertSeeTextassertSeeTextInOrderassertDontSeeassertDontSeeText

若有需要,我們可以將 TestView 實體轉換型別為字串來取得原始的 View 內容轉譯結果:

1$contents = (string) $this->view('welcome');
1$contents = (string) $this->view('welcome');

共用錯誤訊息

有的 View 會使用到 Laravel 所提供的全域 Error Bag中共享的錯誤。若要在全域 Error Bag 中填充錯誤訊息,可使用 withViewErrors 方法:

1$view = $this->withViewErrors([
2 'name' => ['Please provide a valid name.']
3])->view('form');
4 
5$view->assertSee('Please provide a valid name.');
1$view = $this->withViewErrors([
2 'name' => ['Please provide a valid name.']
3])->view('form');
4 
5$view->assertSee('Please provide a valid name.');

Rendering Blade and Components

若有需要,可以使用 blade 方法來取值並轉譯原始的 Blade 字串。與 view 方法類似,blade 方法也會回傳 Illuminate\Testing\TestView 的實體:

1$view = $this->blade(
2 '<x-component :name="$name" />',
3 ['name' => 'Taylor']
4);
5 
6$view->assertSee('Taylor');
1$view = $this->blade(
2 '<x-component :name="$name" />',
3 ['name' => 'Taylor']
4);
5 
6$view->assertSee('Taylor');

可以使用 component 方法來取值並轉譯 Blade 元件component 元件也會回傳 Illuminate\Testing\TestComponent 的實體:

1$view = $this->component(Profile::class, ['name' => 'Taylor']);
2 
3$view->assertSee('Taylor');
1$view = $this->component(Profile::class, ['name' => 'Taylor']);
2 
3$view->assertSee('Taylor');

可用的 Assertion

Response 的 Assertion

Laravel 的 Illuminate\Testing\TestResponse 類別提供了各種自訂 Assertion 方法供我們在測試程式時使用。這些 Assertion 可在 jsongetpostputdelete 測試方法回傳的 Response 上存取:

assertBadRequest

判斷 Response 是否為 Bad Request(錯誤要求) (400) HTTP 狀態碼:

1$response->assertBadRequest();
1$response->assertBadRequest();

assertAccepted

判斷 Response 是否為 Accepted(已接受) (202) HTTP 狀態碼:

1$response->assertAccepted();
1$response->assertAccepted();

assertConflict

判斷 Response 是否為 Conflict(衝突) (409) HTTP 狀態碼:

1$response->assertConflict();
1$response->assertConflict();

判斷 Response 包含給定 Cookie:

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

判斷 Response 包含給定 Cookie,且該 Cookie 已逾期:

1$response->assertCookieExpired($cookieName);
1$response->assertCookieExpired($cookieName);

判斷 Response 包含給定 Cookie,且該 Cookie 未逾期:

1$response->assertCookieNotExpired($cookieName);
1$response->assertCookieNotExpired($cookieName);

判斷 Response 不包含給定 Cookie:

1$response->assertCookieMissing($cookieName);
1$response->assertCookieMissing($cookieName);

assertCreated

判斷 Response 是否為 201 HTTP 狀態碼:

1$response->assertCreated();
1$response->assertCreated();

assertDontSee

判斷程式回傳的 Response 中是否不包含給定字串。除非將第二個引數設為 false,否則該 Assertion 會自動逸出給定的字串:

1$response->assertDontSee($value, $escaped = true);
1$response->assertDontSee($value, $escaped = true);

assertDontSeeText

判斷 Response 的文字中是否不包含給定字串。除非將第二個引數設為 false,否則該 Assertion 會自動逸出給定的字串。該方法會將 Response 的內容傳給 strip_tags PHP 函式,然後再進行判斷:

1$response->assertDontSeeText($value, $escaped = true);
1$response->assertDontSeeText($value, $escaped = true);

assertDownload

判斷 Response 是否為「檔案下載」。一般來說,就表示所叫用的 Route 回傳了 Response::download Response、BinaryFileResponse、 或是 Storage::download Response:

1$response->assertDownload();
1$response->assertDownload();

若有需要,可判斷該下載檔案是否為給定的檔名:

1$response->assertDownload('image.jpg');
1$response->assertDownload('image.jpg');

assertExactJson

判斷 Response 是否包含與給定的 JSON 資料完全相符的內容:

1$response->assertExactJson(array $data);
1$response->assertExactJson(array $data);

assertExactJsonStructure

Assert that the response contains an exact match of the given JSON structure:

1$response->assertExactJsonStructure(array $data);
1$response->assertExactJsonStructure(array $data);

This method is a more strict variant of assertJsonStructure. In contrast with assertJsonStructure, this method will fail if the response contains any keys that aren't explicitly included in the expected JSON structure.

assertForbidden

判斷 Response 是否為 Forbidden(禁止存取) (403) HTTP 狀態碼:

1$response->assertForbidden();
1$response->assertForbidden();

assertFound

判斷 Response 是否為 Found(已找到) (302) HTTP 狀態碼:

1$response->assertFound();
1$response->assertFound();

assertGone

判斷 Response 是否為 Gone(已不再可用) (410) HTTP 狀態碼:

1$response->assertGone();
1$response->assertGone();

assertHeader

判斷 Response 中是否有給定的 Header 與值:

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

assertHeaderMissing

判斷 Response 中是否不含給定的 Header:

1$response->assertHeaderMissing($headerName);
1$response->assertHeaderMissing($headerName);

assertInternalServerError

判斷 Response 是否為「^[Internal Server Error]內部伺服器錯誤」 (500) HTTP 狀態碼:

1$response->assertInternalServerError();
1$response->assertInternalServerError();

assertJson

判斷 Response 是否包含給定的 JSON 資料:

1$response->assertJson(array $data, $strict = false);
1$response->assertJson(array $data, $strict = false);

The assertJson method converts the response to an array to verify that the given array exists within the JSON response returned by the application. So, if there are other properties in the JSON response, this test will still pass as long as the given fragment is present.

assertJsonCount

判斷 Response JSON 是否為一組陣列,且該陣列在給定的索引鍵上有包含預期數量的項目:

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

assertJsonFragment

判斷 Response 中,是否有在任意位置上包含給定的 JSON 資料:

1Route::get('/users', function () {
2 return [
3 'users' => [
4 [
5 'name' => 'Taylor Otwell',
6 ],
7 ],
8 ];
9});
10 
11$response->assertJsonFragment(['name' => 'Taylor Otwell']);
1Route::get('/users', function () {
2 return [
3 'users' => [
4 [
5 'name' => 'Taylor Otwell',
6 ],
7 ],
8 ];
9});
10 
11$response->assertJsonFragment(['name' => 'Taylor Otwell']);

assertJsonIsArray

判斷 Response JSON 為一陣列:

1$response->assertJsonIsArray();
1$response->assertJsonIsArray();

assertJsonIsObject

判斷 Response JSON 為一物件:

1$response->assertJsonIsObject();
1$response->assertJsonIsObject();

assertJsonMissing

判斷 Response 中是否不包含給定的 JSON 資料:

1$response->assertJsonMissing(array $data);
1$response->assertJsonMissing(array $data);

assertJsonMissingExact

判斷 Response 是否不包含完全相符的 JSON 資料:

1$response->assertJsonMissingExact(array $data);
1$response->assertJsonMissingExact(array $data);

assertJsonMissingValidationErrors

判斷 Response 中,給定的索引鍵上是否不含 JSON 驗證錯誤:

1$response->assertJsonMissingValidationErrors($keys);
1$response->assertJsonMissingValidationErrors($keys);
lightbulb

還有一個更泛用的 assertValid 方法,可用來檢查 Response 是否不含以 JSON 格式回傳的驗證錯誤,並檢查 Session Storage 上是否未有快閃存入錯誤訊息。

assertJsonPath

判斷 Response 中在特定路徑上是否包含給定的資料:

1$response->assertJsonPath($path, $expectedValue);
1$response->assertJsonPath($path, $expectedValue);

舉例來說,若程式回傳下列 JSON Response:

1{
2 "user": {
3 "name": "Steve Schoger"
4 }
5}
1{
2 "user": {
3 "name": "Steve Schoger"
4 }
5}

則我們可以像這樣判斷 user 物件的 name 屬性是否符合給定的值:

1$response->assertJsonPath('user.name', 'Steve Schoger');
1$response->assertJsonPath('user.name', 'Steve Schoger');

assertJsonMissingPath

判斷 Response 是否不包含給定的路徑:

1$response->assertJsonMissingPath($path);
1$response->assertJsonMissingPath($path);

舉例來說,若程式回傳下列 JSON Response:

1{
2 "user": {
3 "name": "Steve Schoger"
4 }
5}
1{
2 "user": {
3 "name": "Steve Schoger"
4 }
5}

可以判斷 JSON 是否不包含 user 物件的 email 屬性:

1$response->assertJsonMissingPath('user.email');
1$response->assertJsonMissingPath('user.email');

assertJsonStructure

判斷 Response 是否含有給定的 JSON 結構:

1$response->assertJsonStructure(array $structure);
1$response->assertJsonStructure(array $structure);

舉例來說,若程式回傳了包含下列資料的 JSON Response:

1{
2 "user": {
3 "name": "Steve Schoger"
4 }
5}
1{
2 "user": {
3 "name": "Steve Schoger"
4 }
5}

也可以像這樣檢查 JSON 結構是否符合預期:

1$response->assertJsonStructure([
2 'user' => [
3 'name',
4 ]
5]);
1$response->assertJsonStructure([
2 'user' => [
3 'name',
4 ]
5]);

有時候,程式會回傳的 JSON Response 會包含一組由物件組成的陣列:

1{
2 "user": [
3 {
4 "name": "Steve Schoger",
5 "age": 55,
6 "location": "Earth"
7 },
8 {
9 "name": "Mary Schoger",
10 "age": 60,
11 "location": "Earth"
12 }
13 ]
14}
1{
2 "user": [
3 {
4 "name": "Steve Schoger",
5 "age": 55,
6 "location": "Earth"
7 },
8 {
9 "name": "Mary Schoger",
10 "age": 60,
11 "location": "Earth"
12 }
13 ]
14}

這時,我們可以使用 * 字元來對該陣列中的所有物件進行結構檢查:

1$response->assertJsonStructure([
2 'user' => [
3 '*' => [
4 'name',
5 'age',
6 'location'
7 ]
8 ]
9]);
1$response->assertJsonStructure([
2 'user' => [
3 '*' => [
4 'name',
5 'age',
6 'location'
7 ]
8 ]
9]);

assertJsonValidationErrors

判斷 Response 中,給定的索引鍵上是否有給定的 JSON 驗證錯誤。該方法應用於檢查以 JSON 格式回傳的表單驗證錯誤 Response,而不應用於檢查快閃存入 Session 中的表單驗證錯誤:

1$response->assertJsonValidationErrors(array $data, $responseKey = 'errors');
1$response->assertJsonValidationErrors(array $data, $responseKey = 'errors');
lightbulb

還有一個更泛用的 assertInvalid 方法,可用來檢查 Response 是否包含以 JSON 格式回傳的驗證錯誤,或是 Session Storage 上是否有快閃存入錯誤訊息。

assertJsonValidationErrorFor

判斷 Response 中,給定的索引鍵上是否有任何的 JSON 驗證規則:

1$response->assertJsonValidationErrorFor(string $key, $responseKey = 'errors');
1$response->assertJsonValidationErrorFor(string $key, $responseKey = 'errors');

assertMethodNotAllowed

判斷 Response 是否為 Not Allowed(不允許) (405) HTTP 狀態碼:

1$response->assertMethodNotAllowed();
1$response->assertMethodNotAllowed();

assertMovedPermanently

判斷 Response 是否為 Moved Permanently(已永久移動) (301) HTTP 狀態碼:

1$response->assertMovedPermanently();
1$response->assertMovedPermanently();

assertLocation

判斷 Response 中,Location Header 上是否有給定的 URI 值:

1$response->assertLocation($uri);
1$response->assertLocation($uri);

assertContent

判斷給定字串符合 Response 的內容:

1$response->assertContent($value);
1$response->assertContent($value);

assertNoContent

判斷 Response 是否為給定的 HTTP 狀態碼,且不含內容:

1$response->assertNoContent($status = 204);
1$response->assertNoContent($status = 204);

assertStreamedContent

判斷給定字串符合 Stream(串流) 的 Response 內容:

1$response->assertStreamedContent($value);
1$response->assertStreamedContent($value);

assertNotFound

判斷 Response 是否為 Not Found(找不到) (404) HTTP 狀態碼:

1$response->assertNotFound();
1$response->assertNotFound();

assertOk

判斷 Response 是否為 200 HTTP 狀態碼:

1$response->assertOk();
1$response->assertOk();

assertPaymentRequired

判斷 Response 是否為 Payment Required(需要付費) (402) HTTP 狀態碼:

1$response->assertPaymentRequired();
1$response->assertPaymentRequired();

判斷 Response 是否包含給定未加密的 Cookie:

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

assertRedirect

判斷 Response 是否為指向給定 URI 的重新導向:

1$response->assertRedirect($uri = null);
1$response->assertRedirect($uri = null);

assertRedirectContains

判斷 Response 是否在重新導向至包含給定字串的 URI:

1$response->assertRedirectContains($string);
1$response->assertRedirectContains($string);

assertRedirectToRoute

判斷 Response 是否重新導向到給定的命名 Route

1$response->assertRedirectToRoute($name, $parameters = []);
1$response->assertRedirectToRoute($name, $parameters = []);

assertRedirectToSignedRoute

判斷 Response 是否重新導向到給定的簽名 Route

1$response->assertRedirectToSignedRoute($name = null, $parameters = []);
1$response->assertRedirectToSignedRoute($name = null, $parameters = []);

assertRequestTimeout

判斷 Response 是否為 Request Timeout(要求逾時) (408) HTTP 狀態碼:

1$response->assertRequestTimeout();
1$response->assertRequestTimeout();

assertSee

判斷 Response 中是否包含給定字串。除非將第二個引數設為 false,否則該 Assertion 會自動逸出給定的字串:

1$response->assertSee($value, $escaped = true);
1$response->assertSee($value, $escaped = true);

assertSeeInOrder

判斷 Response 中,是否有依照順序包含給定字串。除非將第二個引數設為 false,否則該 Assertion 會自動逸出給定的字串:

1$response->assertSeeInOrder(array $values, $escaped = true);
1$response->assertSeeInOrder(array $values, $escaped = true);

assertSeeText

判斷 Response 的文字中是否包含給定字串。除非將第二個引數設為 false,否則該 Assertion 會自動逸出給定的字串。該方法會將 Response 的內容傳給 strip_tags PHP 函式,然後再進行判斷:

1$response->assertSeeText($value, $escaped = true);
1$response->assertSeeText($value, $escaped = true);

assertSeeTextInOrder

判斷 Response 的文字中,是否有依照順序出現給定的字串。除非將第二個引數設為 false,否則該 Assertion 會自動逸出給定的字串。該方法會將 Response 的內容傳給 strip_tags PHP 函式,然後再進行判斷:

1$response->assertSeeTextInOrder(array $values, $escaped = true);
1$response->assertSeeTextInOrder(array $values, $escaped = true);

assertServerError

判斷 Response 是否有錯誤的 HTTP 狀態碼 (>= 500 且 < 600):

1$response->assertServerError();
1$response->assertServerError();

assertServiceUnavailable

判斷 Response 是否為「Service Unavailable(服務不可用)」(503) HTTP 狀態碼:

1$response->assertServiceUnavailable();
1$response->assertServiceUnavailable();

assertSessionHas

判斷 Session 是否包含給定的資料:

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

若有需要,assertSessionHas 方法的第二個引數也可以傳入閉包。若閉包回傳 true,則會視為 Assertion 通過:

1$response->assertSessionHas($key, function (User $value) {
2 return $value->name === 'Taylor Otwell';
3});
1$response->assertSessionHas($key, function (User $value) {
2 return $value->name === 'Taylor Otwell';
3});

assertSessionHasInput

判斷 Session 中快閃的輸入陣列內是否包含給定值:

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

若有需要若有需要,assertSessionHasInput 方法的第二個引數也可以傳入閉包。若閉包回傳 true,則會視為 Assertion 通過:

1use Illuminate\Support\Facades\Crypt;
2 
3$response->assertSessionHasInput($key, function (string $value) {
4 return Crypt::decryptString($value) === 'secret';
5});
1use Illuminate\Support\Facades\Crypt;
2 
3$response->assertSessionHasInput($key, function (string $value) {
4 return Crypt::decryptString($value) === 'secret';
5});

assertSessionHasAll

判斷 Session 內是否包含給定的索引鍵/值配對陣列:

1$response->assertSessionHasAll(array $data);
1$response->assertSessionHasAll(array $data);

舉例來說,若網站的 Session 內有 namestatus 索引鍵,則可以像這樣來判斷這兩個欄位是否都存在且為特定的值:

1$response->assertSessionHasAll([
2 'name' => 'Taylor Otwell',
3 'status' => 'active',
4]);
1$response->assertSessionHasAll([
2 'name' => 'Taylor Otwell',
3 'status' => 'active',
4]);

assertSessionHasErrors

判斷 Session 內給定的 $keys 中是否有錯誤。若``$keys` 為關聯式陣列,則會判斷 Session 中,各個欄位 (陣列索引鍵) 是否有特定的錯誤訊息 (陣列值)。請勿使用該方法來測試會回傳 JSON 結構的 Route,請使用該方法來測試將驗證錯誤訊息快閃存入 Session 的 Route:

1$response->assertSessionHasErrors(
2 array $keys = [], $format = null, $errorBag = 'default'
3);
1$response->assertSessionHasErrors(
2 array $keys = [], $format = null, $errorBag = 'default'
3);

舉例來說,若要判斷 nameemail 欄位中是否有快閃存入 Session 的驗證錯誤訊息,可像這樣叫用 assertSessionHasErrors 方法:

1$response->assertSessionHasErrors(['name', 'email']);
1$response->assertSessionHasErrors(['name', 'email']);

或者,也可以判斷給定欄位是否有特定的驗證錯誤訊息:

1$response->assertSessionHasErrors([
2 'name' => 'The given name was invalid.'
3]);
1$response->assertSessionHasErrors([
2 'name' => 'The given name was invalid.'
3]);
lightbulb

還有一個更泛用的 assertInvalid 方法,可用來檢查 Response 是否包含以 JSON 格式回傳的驗證錯誤,或是 Session Storage 上是否有快閃存入錯誤訊息。

assertSessionHasErrorsIn

判斷 Session 中,在特定的 Error Bag 中,給定的 $keys 內是否有錯誤訊息。若 $keys 為關聯式陣列,則會判斷 Session 中各個欄位 (陣列索引鍵) 是否有特定的錯誤訊息 (陣列值):

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

assertSessionHasNoErrors

判斷 Session 中是否無驗證錯誤:

1$response->assertSessionHasNoErrors();
1$response->assertSessionHasNoErrors();

assertSessionDoesntHaveErrors

判斷 Session 中給定的索引鍵是否無驗證錯誤:

1$response->assertSessionDoesntHaveErrors($keys = [], $format = null, $errorBag = 'default');
1$response->assertSessionDoesntHaveErrors($keys = [], $format = null, $errorBag = 'default');
lightbulb

還有一個更泛用的 assertValid 方法,可用來檢查 Response 是否不含以 JSON 格式回傳的驗證錯誤,並檢查 Session Storage 上是否未有快閃存入錯誤訊息。

assertSessionMissing

判斷 Session 中是否不包含給定的索引鍵:

1$response->assertSessionMissing($key);
1$response->assertSessionMissing($key);

assertStatus

判斷 Response 是否回傳給定的 HTTP 狀態碼:

1$response->assertStatus($code);
1$response->assertStatus($code);

assertSuccessful

判斷 Response 是否有成功的 HTTP 狀態碼 (>= 200 且 < 300):

1$response->assertSuccessful();
1$response->assertSuccessful();

assertTooManyRequests

判斷 Response 是否為 Too Many Requests(過多要求) (429) HTTP 狀態碼:

1$response->assertTooManyRequests();
1$response->assertTooManyRequests();

assertUnauthorized

判斷 Response 是否為禁止存取 (401) HTTP 狀態碼:

1$response->assertUnauthorized();
1$response->assertUnauthorized();

assertUnprocessable

判斷 Response 是否為無法處理 (422) HTTP 狀態碼:

1$response->assertUnprocessable();
1$response->assertUnprocessable();

assertUnsupportedMediaType

判斷 Response 是否為 Unsupported Media Type(不支援的媒體格式) (415) HTTP 狀態碼:

1$response->assertUnsupportedMediaType();
1$response->assertUnsupportedMediaType();

assertValid

判斷 Response 中,不包含給定索引鍵的驗證錯誤。該方法可用來判斷以 JSON 結構回傳驗證錯誤,或是將驗證錯誤快閃存入 Session 的 Response:

1// Assert that no validation errors are present...
2$response->assertValid();
3 
4// Assert that the given keys do not have validation errors...
5$response->assertValid(['name', 'email']);
1// Assert that no validation errors are present...
2$response->assertValid();
3 
4// Assert that the given keys do not have validation errors...
5$response->assertValid(['name', 'email']);

assertInvalid

判斷 Response 中,給定的索引鍵是否有驗證錯誤訊息。該方法可用於檢查以 JSON 格式回傳錯誤訊息,或是將驗證錯誤訊息快閃存入 Session 的 Response:

1$response->assertInvalid(['name', 'email']);
1$response->assertInvalid(['name', 'email']);

也可以判斷給定的索引鍵是否有特定的錯誤訊息。在判斷是否有特定的錯誤訊息時,可提供完整的訊息,或是其中一段的錯誤訊息:

1$response->assertInvalid([
2 'name' => 'The name field is required.',
3 'email' => 'valid email address',
4]);
1$response->assertInvalid([
2 'name' => 'The name field is required.',
3 'email' => 'valid email address',
4]);

assertViewHas

判斷 Response View 中是否包含給定的一部分資料:

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

若在 assertViewHas 方法中的第二個引數傳入閉包,則可檢查並針對一部分的資料做 Assertion:

1$response->assertViewHas('user', function (User $user) {
2 return $user->name === 'Taylor';
3});
1$response->assertViewHas('user', function (User $user) {
2 return $user->name === 'Taylor';
3});

此外,也可以在 Response 上以陣列變數的形式來存取 View Data,讓我們可以方便地檢查這些值:

1expect($response['name'])->toBe('Taylor');
1expect($response['name'])->toBe('Taylor');
1$this->assertEquals('Taylor', $response['name']);
1$this->assertEquals('Taylor', $response['name']);

assertViewHasAll

判斷 Response View 中是否包含一組資料:

1$response->assertViewHasAll(array $data);
1$response->assertViewHasAll(array $data);

該方法可用於檢查 View 中是否含有符合給定索引鍵的資料:

1$response->assertViewHasAll([
2 'name',
3 'email',
4]);
1$response->assertViewHasAll([
2 'name',
3 'email',
4]);

或者,也可以判斷是否包含特定的 View Data,且這些資料是否為指定的值:

1$response->assertViewHasAll([
2 'name' => 'Taylor Otwell',
3 'email' => '[email protected],',
4]);
1$response->assertViewHasAll([
2 'name' => 'Taylor Otwell',
3 'email' => '[email protected],',
4]);

assertViewIs

判斷 Route 是否回傳給定的 View:

1$response->assertViewIs($value);
1$response->assertViewIs($value);

assertViewMissing

判斷程式回傳的 Reponse 中,是否不含給定的資料索引鍵:

1$response->assertViewMissing($key);
1$response->assertViewMissing($key);

身份驗證 Assertion

Laravel 也提供了各種與身份驗證相關的 Assertion,讓我們能在專案的 Feature Test 中使用。請注意,這些方法需要在 Test Class 上呼叫,而不是在 getpost 方法回傳的 Illuminate\Testing\TestResponse實體上呼叫。

assertAuthenticated

判斷使用者已登入:

1$this->assertAuthenticated($guard = null);
1$this->assertAuthenticated($guard = null);

assertGuest

判斷使用者是否未登入:

1$this->assertGuest($guard = null);
1$this->assertGuest($guard = null);

assertAuthenticatedAs

判斷是否已登入特定的使用者:

1$this->assertAuthenticatedAs($user, $guard = null);
1$this->assertAuthenticatedAs($user, $guard = null);

Validation 的 Assertion

Laravel 提供的 Assertion 中,主要有兩種是用來針對 Validation 判斷的,可用來確保 Request 中的資料是有效或無效的。

assertValid

判斷 Response 中,不包含給定索引鍵的驗證錯誤。該方法可用來判斷以 JSON 結構回傳驗證錯誤,或是將驗證錯誤快閃存入 Session 的 Response:

1// Assert that no validation errors are present...
2$response->assertValid();
3 
4// Assert that the given keys do not have validation errors...
5$response->assertValid(['name', 'email']);
1// Assert that no validation errors are present...
2$response->assertValid();
3 
4// Assert that the given keys do not have validation errors...
5$response->assertValid(['name', 'email']);

assertInvalid

判斷 Response 中,給定的索引鍵是否有驗證錯誤訊息。該方法可用於檢查以 JSON 格式回傳錯誤訊息,或是將驗證錯誤訊息快閃存入 Session 的 Response:

1$response->assertInvalid(['name', 'email']);
1$response->assertInvalid(['name', 'email']);

也可以判斷給定的索引鍵是否有特定的錯誤訊息。在判斷是否有特定的錯誤訊息時,可提供完整的訊息,或是其中一段的錯誤訊息:

1$response->assertInvalid([
2 'name' => 'The name field is required.',
3 'email' => 'valid email address',
4]);
1$response->assertInvalid([
2 'name' => 'The name field is required.',
3 'email' => 'valid email address',
4]);
翻譯進度
47.28% 已翻譯
更新時間:
2024年6月30日 上午8:27:00 [世界標準時間]
翻譯人員:
幫我們翻譯此頁

留言

尚無留言

“Laravel” is a Trademark of Taylor Otwell.
The source documentation is released under MIT license. See laravel/docs on GitHub for details.
The translated documentations are released under MIT license. See cornch/laravel-docs-l10n on GitHub for details.