HTTP 測試
簡介
Laravel 提供了一個非常流暢的 API,用於向你的應用程式發起 HTTP 請求並檢查響應。例如,請看下面定義的特性測試:
1<?php2 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(): void13 {14 $response = $this->get('/');15 16 $response->assertStatus(200);17 }18}
get 方法嚮應用程式發起 GET 請求,而 assertStatus 方法斷言返回的響應應具有給定的 HTTP 狀態碼。除了這個簡單的斷言外,Laravel 還包含各種用於檢查響應頭、內容、JSON 結構等的斷言。
發起請求
要向你的應用程式發起請求,你可以在測試中使用 get、post、put、patch 或 delete 方法。這些方法實際上並不會向你的應用程式發起“真實”的 HTTP 請求。相反,整個網路請求是在內部模擬的。
測試請求方法返回的不是 Illuminate\Http\Response 例項,而是 Illuminate\Testing\TestResponse 例項,它提供了各種有用的斷言,允許你檢查應用程式的響應。
1<?php2 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(): void13 {14 $response = $this->get('/');15 16 $response->assertStatus(200);17 }18}
通常情況下,你的每個測試都應該只嚮應用程式發起一次請求。如果在單個測試方法中執行多次請求,可能會出現意外行為。
為方便起見,執行測試時 CSRF 中介軟體會自動停用。
自定義請求頭
你可以使用 withHeaders 方法在請求傳送到應用程式之前自定義請求頭。此方法允許你為請求新增任何你想要的自定義請求頭。
1<?php2 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(): void13 {14 $response = $this->withHeaders([15 'X-Header' => 'Value',16 ])->post('/user', ['name' => 'Sally']);17 18 $response->assertStatus(201);19 }20}
Cookies
你可以使用 withCookie 或 withCookies 方法在發起請求之前設定 cookie 值。withCookie 方法接受 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 3namespace Tests\Feature; 4 5use Tests\TestCase; 6 7class ExampleTest extends TestCase 8{ 9 public function test_interacting_with_cookies(): void10 {11 $response = $this->withCookie('color', 'blue')->get('/');12 13 $response = $this->withCookies([14 'color' => 'blue',15 'name' => 'Taylor',16 ])->get('/');17 18 //19 }20}
會話 / 身份驗證
Laravel 提供了幾個在 HTTP 測試期間與會話互動的輔助方法。首先,你可以使用 withSession 方法將會話資料設定為給定的陣列。這在嚮應用程式發起請求之前載入會話資料非常有用。
1<?php2 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(): void10 {11 $response = $this->withSession(['banned' => false])->get('/');12 13 //14 }15}
Laravel 的會話通常用於為當前經過身份驗證的使用者維護狀態。因此,actingAs 輔助方法提供了一種簡單的方法來將給定使用者驗證為當前使用者。例如,我們可以使用模型工廠來生成並驗證使用者。
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(): void11 {12 $user = User::factory()->create();13 14 $response = $this->actingAs($user)15 ->withSession(['banned' => false])16 ->get('/');17 18 //19 }20}
你還可以透過將守衛(guard)名稱作為第二個引數傳遞給 actingAs 方法,來指定應該使用哪個守衛來驗證給定使用者。提供給 actingAs 方法的守衛也將成為測試期間的預設守衛。
1$this->actingAs($user, 'web');
如果你想確保請求處於未驗證狀態,可以使用 actingAsGuest 方法。
1$this->actingAsGuest();
除錯響應
在嚮應用程式發起測試請求後,可以使用 dump、dumpHeaders 和 dumpSession 方法來檢查和除錯響應內容。
1<?php2 3test('basic test', function () {4 $response = $this->get('/');5 6 $response->dump();7 $response->dumpHeaders();8 $response->dumpSession();9});
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(): void13 {14 $response = $this->get('/');15 16 $response->dump();17 $response->dumpHeaders();18 $response->dumpSession();19 }20}
或者,你可以使用 dd、ddHeaders、ddBody、ddJson 和 ddSession 方法來轉儲有關響應的資訊,然後停止執行。
1<?php 2 3test('basic test', function () { 4 $response = $this->get('/'); 5 6 $response->dd(); 7 $response->ddHeaders(); 8 $response->ddBody(); 9 $response->ddJson();10 $response->ddSession();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(): void13 {14 $response = $this->get('/');15 16 $response->dd();17 $response->ddHeaders();18 $response->ddBody();19 $response->ddJson();20 $response->ddSession();21 }22}
異常處理
有時你可能需要測試應用程式是否丟擲了特定異常。為此,你可以透過 Exceptions 門面(facade)來“偽造”異常處理程式。一旦偽造了異常處理程式,你就可以利用 assertReported 和 assertNotReported 方法對請求期間丟擲的異常進行斷言。
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 TestCase10{11 /**12 * A basic test example.13 */14 public function test_exception_is_thrown(): void15 {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}
assertNotReported 和 assertNothingReported 方法可用於斷言請求期間未丟擲給定異常,或未丟擲任何異常。
1Exceptions::assertNotReported(InvalidOrderException::class);2 3Exceptions::assertNothingReported();
你可以在發起請求之前呼叫 withoutExceptionHandling 方法,徹底停用給定請求的異常處理。
1$response = $this->withoutExceptionHandling()->get('/');
此外,如果你想確保你的應用程式沒有使用 PHP 語言或應用程式所依賴的庫已棄用的功能,你可以在發起請求之前呼叫 withoutDeprecationHandling 方法。當停用棄用處理時,棄用警告將被轉換為異常,從而導致測試失敗。
1$response = $this->withoutDeprecationHandling()->get('/');
assertThrows 方法可用於斷言給定閉包內的程式碼丟擲了指定型別的異常。
1$this->assertThrows(2 fn () => (new ProcessOrder)->execute(),3 OrderInvalid::class4);
如果你想檢查丟擲的異常並對其進行斷言,可以將一個閉包作為 assertThrows 方法的第二個引數傳入。
1$this->assertThrows(2 fn () => (new ProcessOrder)->execute(),3 fn (OrderInvalid $e) => $e->orderId() === 123;4);
assertDoesntThrow 方法可用於斷言給定閉包內的程式碼不會丟擲任何異常。
1$this->assertDoesntThrow(fn () => (new ProcessOrder)->execute());
測試 JSON API
Laravel 還提供了幾個用於測試 JSON API 及其響應的輔助方法。例如,json、getJson、postJson、putJson、patchJson、deleteJson 和 optionsJson 方法可用於使用各種 HTTP 謂詞發起 JSON 請求。你還可以輕鬆地將資料和請求頭傳遞給這些方法。首先,讓我們編寫一個測試,向 /api/user 發起 POST 請求,並斷言返回了預期的 JSON 資料。
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(): void13 {14 $response = $this->postJson('/api/user', ['name' => 'Sally']);15 16 $response17 ->assertStatus(201)18 ->assertJson([19 'created' => true,20 ]);21 }22}
此外,JSON 響應資料可以作為響應物件上的陣列變數進行訪問,這使你能夠方便地檢查 JSON 響應中返回的各個值。
1expect($response['created'])->toBeTrue();
1$this->assertTrue($response['created']);
assertJson 方法將響應轉換為陣列,以驗證給定陣列是否存在於應用程式返回的 JSON 響應中。因此,如果 JSON 響應中還有其他屬性,只要存在給定的片段,此測試仍然會透過。
斷言精確的 JSON 匹配
如前所述,assertJson 方法可用於斷言 JSON 片段存在於 JSON 響應中。如果你想驗證給定陣列是否完全匹配應用程式返回的 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 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(): void13 {14 $response = $this->postJson('/user', ['name' => 'Sally']);15 16 $response17 ->assertStatus(201)18 ->assertExactJson([19 'created' => true,20 ]);21 }22}
在 JSON 路徑上進行斷言
如果你想驗證 JSON 響應在指定路徑是否包含給定的資料,你應該使用 assertJsonPath 方法。
1<?php2 3test('asserting a json path value', function () {4 $response = $this->postJson('/user', ['name' => 'Sally']);5 6 $response7 ->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(): void13 {14 $response = $this->postJson('/user', ['name' => 'Sally']);15 16 $response17 ->assertStatus(201)18 ->assertJsonPath('team.owner.name', 'Darian');19 }20}
assertJsonPath 方法也接受一個閉包,該閉包可用於動態判斷斷言是否應該透過。
1$response->assertJsonPath('team.owner.name', fn (string $name) => strlen($name) >= 3);
流式 JSON 測試
Laravel 還提供了一種優美的方式來流式測試應用程式的 JSON 響應。首先,將一個閉包傳遞給 assertJson 方法。此閉包將被呼叫,並接收一個 Illuminate\Testing\Fluent\AssertableJson 例項,該例項可用於對應用程式返回的 JSON 進行斷言。where 方法可用於對 JSON 的特定屬性進行斷言,而 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')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 $response11 ->assertJson(fn (AssertableJson $json) =>12 $json->where('id', 1)13 ->where('name', 'Victoria Faith')15 ->whereNot('status', 'pending')16 ->missing('password')17 ->etc()18 );19}
理解 etc 方法
在上面的示例中,你可能注意到我們在斷言鏈的末尾呼叫了 etc 方法。此方法通知 Laravel JSON 物件中可能還存在其他屬性。如果未使用 etc 方法,且 JSON 物件中存在你未進行斷言的其他屬性,測試將會失敗。
這種行為背後的意圖是透過強制你明確地對屬性進行斷言,或者透過 etc 方法顯式允許附加屬性,來保護你不無意中洩露 JSON 響應中的敏感資訊。
但是,你應該意識到,在斷言鏈中不包含 etc 方法並不能確保 JSON 物件中巢狀的陣列內沒有新增額外的屬性。etc 方法僅確保在呼叫 etc 方法的巢狀級別不存在額外的屬性。
斷言屬性的存在/缺失
要斷言屬性存在或缺失,可以使用 has 和 missing 方法。
1$response->assertJson(fn (AssertableJson $json) =>2 $json->has('data')3 ->missing('message')4);
此外,hasAll 和 missingAll 方法允許同時斷言多個屬性的存在或缺失。
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);
針對 JSON 集合進行斷言
通常,你的路由會返回包含多個條目的 JSON 響應,例如多個使用者。
1Route::get('/users', function () {2 return User::all();3});
在這種情況下,我們可以使用流式 JSON 物件的 has 方法來對響應中包含的使用者進行斷言。例如,我們斷言 JSON 響應包含三個使用者。接下來,我們將使用 first 方法對集合中的第一個使用者進行一些斷言。first 方法接受一個閉包,該閉包接收另一個可斷言的 JSON 字串,我們可以使用它對 JSON 集合中的第一個物件進行斷言。
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') 8 ->missing('password') 9 ->etc()10 )11 );
如果你想對 JSON 集合中的每一項進行相同的斷言,可以使用 each 方法。
1$response 2 ->assertJson(fn (AssertableJson $json) => 3 $json->has(3) 4 ->each(fn (AssertableJson $json) => 5 $json->whereType('id', 'integer') 6 ->whereType('name', 'string') 7 ->whereType('email', 'string') 8 ->missing('password') 9 ->etc()10 )11 );
限定 JSON 集合斷言的作用域
有時,應用程式的路由會返回分配了命名鍵的 JSON 集合。
1Route::get('/users', function () {2 return [3 'meta' => [...],4 'users' => User::all(),5 ];6})
測試這些路由時,可以使用 has 方法來斷言集合中條目的數量。此外,還可以使用 has 方法來限定斷言鏈的作用域。
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') 9 ->missing('password')10 ->etc()11 )12 );
但是,無需兩次呼叫 has 方法來對 users 集合進行斷言,你可以只調用一次,並將閉包作為其第三個引數。執行此操作時,閉包將被自動呼叫,並限定在集合的第一項中。
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') 8 ->missing('password') 9 ->etc()10 )11 );
斷言 JSON 型別
你可能只想斷言 JSON 響應中的屬性屬於某種特定型別。Illuminate\Testing\Fluent\AssertableJson 類提供了 whereType 和 whereAllType 方法來做到這一點。
1$response->assertJson(fn (AssertableJson $json) =>2 $json->whereType('id', 'integer')3 ->whereAllType([4 'users.0.name' => 'string',5 'meta' => 'array'6 ])7);
你可以使用 | 字元指定多種型別,或者將型別陣列作為 whereType 方法的第二個引數傳遞。如果響應值是列出的任何型別,則斷言成功。
1$response->assertJson(fn (AssertableJson $json) =>2 $json->whereType('name', 'string|null')3 ->whereType('id', ['string', 'integer'])4);
whereType 和 whereAllType 方法可識別以下型別:string、integer、double、boolean、array 和 null。
測試檔案上傳
Illuminate\Http\UploadedFile 類提供了一個 fake 方法,可用於生成用於測試的虛擬檔案或影像。這與 Storage 門面的 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 3namespace Tests\Feature; 4 5use Illuminate\Http\UploadedFile; 6use Illuminate\Support\Facades\Storage; 7use Tests\TestCase; 8 9class ExampleTest extends TestCase10{11 public function test_avatars_can_be_uploaded(): void12 {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 門面提供的 assertMissing 方法。
1Storage::fake('avatars');2 3// ...4 5Storage::disk('avatars')->assertMissing('missing.jpg');
偽造檔案自定義
當使用 UploadedFile 類提供的 fake 方法建立檔案時,你可以指定影像的寬度、高度和大小(以千位元組為單位),以便更好地測試應用程式的驗證規則。
1UploadedFile::fake()->image('avatar.jpg', $width, $height)->size(100);
除了建立影像外,你還可以使用 create 方法建立任何其他型別的檔案。
1UploadedFile::fake()->create('document.pdf', $sizeInKilobytes);
如果需要,你可以將 $mimeType 引數傳遞給該方法,以明確定義檔案應返回的 MIME 型別。
1UploadedFile::fake()->create(2 'document.pdf', $sizeInKilobytes, 'application/pdf'3);
測試檢視
Laravel 還允許你在不向應用程式發起模擬 HTTP 請求的情況下渲染檢視。為此,你可以在測試中呼叫 view 方法。view 方法接受檢視名稱和可選的資料陣列。該方法返回一個 Illuminate\Testing\TestView 例項,它提供了多種方法來方便地對檢視內容進行斷言。
1<?php2 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(): void10 {11 $view = $this->view('welcome', ['name' => 'Taylor']);12 13 $view->assertSee('Taylor');14 }15}
TestView 類提供以下斷言方法:assertSee、assertSeeInOrder、assertSeeText、assertSeeTextInOrder、assertDontSee 和 assertDontSeeText。
如果需要,你可以透過將 TestView 例項轉換為字串來獲取原始的、已渲染的檢視內容。
1$contents = (string) $this->view('welcome');
共享錯誤
某些檢視可能依賴於Laravel 提供的全域性錯誤包中共享的錯誤。要使用錯誤訊息填充錯誤包,可以使用 withViewErrors 方法。
1$view = $this->withViewErrors([2 'name' => ['Please provide a valid name.']3])->view('form');4 5$view->assertSee('Please provide a valid name.');
渲染 Blade 與元件
如有必要,你可以使用 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');
你可以使用 component 方法來計算並渲染 Blade 元件。component 方法返回一個 Illuminate\Testing\TestComponent 例項。
1$view = $this->component(Profile::class, ['name' => 'Taylor']);2 3$view->assertSee('Taylor');
快取路由
在測試執行之前,Laravel 會啟動一個新的應用程式例項,包括收集所有定義的路由。如果你的應用程式有很多路由檔案,你可能希望在測試用例中新增 Illuminate\Foundation\Testing\WithCachedRoutes trait。在使用此 trait 的測試中,路由會被構建一次並存儲在記憶體中,這意味著路由收集過程在整個測試套件中只會執行一次。
1<?php 2 3use App\Http\Controllers\UserController; 4use Illuminate\Foundation\Testing\WithCachedRoutes; 5 6pest()->use(WithCachedRoutes::class); 7 8test('basic example', function () { 9 $this->get(action([UserController::class, 'index']));10 11 // ...12});
1<?php 2 3namespace Tests\Feature; 4 5use App\Http\Controllers\UserController; 6use Illuminate\Foundation\Testing\WithCachedRoutes; 7use Tests\TestCase; 8 9class BasicTest extends TestCase10{11 use WithCachedRoutes;12 13 /**14 * A basic functional test example.15 */16 public function test_basic_example(): void17 {18 $response = $this->get(action([UserController::class, 'index']));19 20 // ...21 }22}
可用斷言
響應斷言
Laravel 的 Illuminate\Testing\TestResponse 類提供了多種自定義斷言方法,你可以在測試應用程式時使用。這些斷言可以在 json、get、post、put 和 delete 測試方法返回的響應上訪問。
assertAccepted assertBadRequest assertClientError assertConflict assertCookie assertCookieExpired assertCookieNotExpired assertCookieMissing assertCreated assertDontSee assertDontSeeText assertDownload assertExactJson assertExactJsonStructure assertForbidden assertFound assertGone assertHeader assertHeaderContains assertHeaderMissing assertInternalServerError assertJson assertJsonCount assertJsonFragment assertJsonIsArray assertJsonIsObject assertJsonMissing assertJsonMissingExact assertJsonMissingValidationErrors assertJsonPath assertJsonMissingPath assertJsonStructure assertJsonValidationErrors assertJsonValidationErrorFor assertLocation assertMethodNotAllowed assertMovedPermanently assertContent assertNoContent assertStreamed assertStreamedContent assertNotFound assertOk assertPaymentRequired assertPlainCookie assertRedirect assertRedirectBack assertRedirectBackWithErrors assertRedirectBackWithoutErrors assertRedirectContains assertRedirectToRoute assertRedirectToSignedRoute assertRequestTimeout assertSee assertSeeInOrder assertSeeText assertSeeTextInOrder assertServerError assertServiceUnavailable assertSessionHas assertSessionHasInput assertSessionHasAll assertSessionHasErrors assertSessionHasErrorsIn assertSessionHasNoErrors assertSessionDoesntHaveErrors assertSessionMissing assertStatus assertSuccessful assertTooManyRequests assertUnauthorized assertUnprocessable assertUnsupportedMediaType assertValid assertInvalid assertViewHas assertViewHasAll assertViewIs assertViewMissing
assertAccepted
斷言響應具有已接受 (202) HTTP 狀態碼
1$response->assertAccepted();
assertBadRequest
斷言響應具有錯誤請求 (400) HTTP 狀態碼
1$response->assertBadRequest();
assertClientError
斷言響應具有客戶端錯誤 (>= 400, < 500) HTTP 狀態碼
1$response->assertClientError();
assertConflict
斷言響應具有衝突 (409) HTTP 狀態碼
1$response->assertConflict();
assertCookie
斷言響應包含給定的 cookie
1$response->assertCookie($cookieName, $value = null);
assertCookieExpired
斷言響應包含給定的 cookie 且該 cookie 已過期
1$response->assertCookieExpired($cookieName);
assertCookieNotExpired
斷言響應包含給定的 cookie 且該 cookie 未過期
1$response->assertCookieNotExpired($cookieName);
assertCookieMissing
斷言響應不包含給定的 cookie
1$response->assertCookieMissing($cookieName);
assertCreated
斷言響應具有 201 HTTP 狀態碼
1$response->assertCreated();
assertDontSee
斷言給定的字串不包含在應用程式返回的響應中。此斷言將自動轉義給定的字串,除非你傳入 false 作為第二個引數
1$response->assertDontSee($value, $escape = true);
assertDontSeeText
斷言給定的字串不包含在響應文字中。此斷言將自動轉義給定的字串,除非你傳入 false 作為第二個引數。此方法在進行斷言之前會將響應內容傳遞給 PHP 的 strip_tags 函式
1$response->assertDontSeeText($value, $escape = true);
assertDownload
斷言響應為“下載”。通常,這意味著返回響應的被呼叫路由返回了 Response::download 響應、BinaryFileResponse 或 Storage::download 響應
1$response->assertDownload();
如果你願意,你可以斷言可下載檔案被分配了給定的檔名
1$response->assertDownload('image.jpg');
assertExactJson
斷言響應包含給定的 JSON 資料的精確匹配
1$response->assertExactJson(array $data);
assertExactJsonStructure
斷言響應包含給定的 JSON 結構的精確匹配
1$response->assertExactJsonStructure(array $data);
此方法是 assertJsonStructure 的一個更嚴格的變體。與 assertJsonStructure 不同,如果響應包含任何未顯式包含在預期 JSON 結構中的鍵,此方法將會失敗。
assertForbidden
斷言響應具有禁止訪問 (403) HTTP 狀態碼
1$response->assertForbidden();
assertFound
斷言響應具有已找到 (302) HTTP 狀態碼
1$response->assertFound();
assertGone
斷言響應具有已刪除 (410) HTTP 狀態碼
1$response->assertGone();
assertHeader
斷言響應上存在給定的頭和值
1$response->assertHeader($headerName, $value = null);
assertHeaderContains
斷言給定的頭包含給定的子字串值
1$response->assertHeaderContains($headerName, $value);
assertHeaderMissing
斷言響應上不存在給定的頭
1$response->assertHeaderMissing($headerName);
assertInternalServerError
斷言響應具有“內部伺服器錯誤” (500) HTTP 狀態碼
1$response->assertInternalServerError();
assertJson
斷言響應包含給定的 JSON 資料
1$response->assertJson(array $data, $strict = false);
assertJson 方法將響應轉換為陣列,以驗證給定陣列是否存在於應用程式返回的 JSON 響應中。因此,如果 JSON 響應中還有其他屬性,只要存在給定的片段,此測試仍然會透過。
assertJsonCount
斷言響應 JSON 在給定鍵處有一個包含預期數量條目的陣列
1$response->assertJsonCount($count, $key = null);
assertJsonFragment
斷言響應在響應的任何位置包含給定的 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']);
assertJsonIsArray
斷言響應 JSON 是一個數組
1$response->assertJsonIsArray();
assertJsonIsObject
斷言響應 JSON 是一個物件
1$response->assertJsonIsObject();
assertJsonMissing
斷言響應不包含給定的 JSON 資料
1$response->assertJsonMissing(array $data);
assertJsonMissingExact
斷言響應不包含精確的 JSON 資料
1$response->assertJsonMissingExact(array $data);
assertJsonMissingValidationErrors
斷言響應對於給定鍵沒有 JSON 驗證錯誤
1$response->assertJsonMissingValidationErrors($keys);
更通用的 assertValid 方法可用於斷言響應沒有作為 JSON 返回的驗證錯誤,並且沒有錯誤快閃記憶體到會話儲存中。
assertJsonPath
斷言響應在指定路徑包含給定的資料
1$response->assertJsonPath($path, $expectedValue);
例如,如果你的應用程式返回以下 JSON 響應
1{2 "user": {3 "name": "Steve Schoger"4 }5}
你可以像這樣斷言 user 物件的 name 屬性與給定值匹配
1$response->assertJsonPath('user.name', 'Steve Schoger');
assertJsonMissingPath
斷言響應不包含給定的路徑
1$response->assertJsonMissingPath($path);
例如,如果你的應用程式返回以下 JSON 響應
1{2 "user": {3 "name": "Steve Schoger"4 }5}
你可以斷言它不包含 user 物件的 email 屬性
1$response->assertJsonMissingPath('user.email');
assertJsonStructure
斷言響應具有給定的 JSON 結構
1$response->assertJsonStructure(array $structure);
例如,如果你的應用程式返回的 JSON 響應包含以下資料
1{2 "user": {3 "name": "Steve Schoger"4 }5}
你可以像這樣斷言 JSON 結構符合你的預期
1$response->assertJsonStructure([2 'user' => [3 'name',4 ]5]);
有時,你的應用程式返回的 JSON 響應可能包含物件陣列
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]);
assertJsonValidationErrors
斷言響應對於給定鍵具有給定的 JSON 驗證錯誤。此方法應在斷言驗證錯誤作為 JSON 結構返回而不是快閃記憶體到會話的響應時使用
1$response->assertJsonValidationErrors(array $data, $responseKey = 'errors');
更通用的 assertInvalid 方法可用於斷言響應有作為 JSON 返回的驗證錯誤,或有錯誤快閃記憶體到會話儲存中。
assertJsonValidationErrorFor
斷言響應對於給定鍵有任何 JSON 驗證錯誤
1$response->assertJsonValidationErrorFor(string $key, $responseKey = 'errors');
assertMethodNotAllowed
斷言響應具有方法不被允許 (405) HTTP 狀態碼
1$response->assertMethodNotAllowed();
assertMovedPermanently
斷言響應具有永久移動 (301) HTTP 狀態碼
1$response->assertMovedPermanently();
assertLocation
斷言響應的 Location 頭中具有給定的 URI 值
1$response->assertLocation($uri);
assertContent
斷言給定的字串與響應內容匹配
1$response->assertContent($value);
assertNoContent
斷言響應具有給定的 HTTP 狀態碼且沒有內容
1$response->assertNoContent($status = 204);
assertStreamed
斷言響應是流式響應
1$response->assertStreamed();
assertStreamedContent
斷言給定的字串與流式響應內容匹配
1$response->assertStreamedContent($value);
assertNotFound
斷言響應具有未找到 (404) HTTP 狀態碼
1$response->assertNotFound();
assertOk
斷言響應具有 200 HTTP 狀態碼
1$response->assertOk();
assertPaymentRequired
斷言響應具有需要付款 (402) HTTP 狀態碼
1$response->assertPaymentRequired();
assertPlainCookie
斷言響應包含給定的未加密 cookie
1$response->assertPlainCookie($cookieName, $value = null);
assertRedirect
斷言響應是重定向到給定 URI
1$response->assertRedirect($uri = null);
assertRedirectBack
斷言響應是否重定向回上一頁
1$response->assertRedirectBack();
assertRedirectBackWithErrors
斷言響應是否重定向回上一頁,且會話具有給定的錯誤
1$response->assertRedirectBackWithErrors(2 array $keys = [], $format = null, $errorBag = 'default'3);
assertRedirectBackWithoutErrors
斷言響應是否重定向回上一頁,且會話不包含任何錯誤訊息
1$response->assertRedirectBackWithoutErrors();
assertRedirectContains
斷言響應是否重定向到包含給定字串的 URI
1$response->assertRedirectContains($string);
assertRedirectToRoute
斷言響應是重定向到給定的命名路由
1$response->assertRedirectToRoute($name, $parameters = []);
assertRedirectToSignedRoute
斷言響應是重定向到給定的簽名路由
1$response->assertRedirectToSignedRoute($name = null, $parameters = []);
assertRequestTimeout
斷言響應具有請求超時 (408) HTTP 狀態碼
1$response->assertRequestTimeout();
assertSee
斷言響應中包含給定的字串。此斷言將自動轉義給定的字串,除非你傳入 false 作為第二個引數
1$response->assertSee($value, $escape = true);
assertSeeInOrder
斷言響應中按順序包含給定的字串。此斷言將自動轉義給定的字串,除非你傳入 false 作為第二個引數
1$response->assertSeeInOrder(array $values, $escape = true);
assertSeeText
斷言響應文字中包含給定的字串。此斷言將自動轉義給定的字串,除非你傳入 false 作為第二個引數。在進行斷言之前,響應內容將傳遞給 PHP 的 strip_tags 函式
1$response->assertSeeText($value, $escape = true);
assertSeeTextInOrder
斷言響應文字中按順序包含給定的字串。此斷言將自動轉義給定的字串,除非你傳入 false 作為第二個引數。在進行斷言之前,響應內容將傳遞給 PHP 的 strip_tags 函式
1$response->assertSeeTextInOrder(array $values, $escape = true);
assertServerError
斷言響應具有伺服器錯誤 (>= 500, < 600) HTTP 狀態碼
1$response->assertServerError();
assertServiceUnavailable
斷言響應具有“服務不可用” (503) HTTP 狀態碼
1$response->assertServiceUnavailable();
assertSessionHas
斷言會話包含給定的一段資料
1$response->assertSessionHas($key, $value = null);
如果需要,可以將閉包作為第二個引數提供給 assertSessionHas 方法。如果閉包返回 true,則斷言透過
1$response->assertSessionHas($key, function (User $value) {2 return $value->name === 'Taylor Otwell';3});
assertSessionHasInput
斷言會話在快閃記憶體輸入陣列中具有給定的值
1$response->assertSessionHasInput($key, $value = null);
如果需要,可以將閉包作為第二個引數提供給 assertSessionHasInput 方法。如果閉包返回 true,則斷言透過
1use Illuminate\Support\Facades\Crypt;2 3$response->assertSessionHasInput($key, function (string $value) {4 return Crypt::decryptString($value) === 'secret';5});
assertSessionHasAll
斷言會話包含給定的鍵/值對陣列
1$response->assertSessionHasAll(array $data);
例如,如果你的應用程式會話包含 name 和 status 鍵,你可以像這樣斷言兩者都存在且具有指定的值
1$response->assertSessionHasAll([2 'name' => 'Taylor Otwell',3 'status' => 'active',4]);
assertSessionHasErrors
斷言會話包含給定 $keys 的錯誤。如果 $keys 是關聯陣列,則斷言會話對於每個欄位(鍵)包含特定的錯誤訊息(值)。此方法應在測試將驗證錯誤快閃記憶體到會話而不是以 JSON 結構返回它們的路由時使用
1$response->assertSessionHasErrors(2 array $keys = [], $format = null, $errorBag = 'default'3);
例如,要斷言 name 和 email 欄位有快閃記憶體到會話的驗證錯誤訊息,你可以像這樣呼叫 assertSessionHasErrors 方法
1$response->assertSessionHasErrors(['name', 'email']);
或者,你可以斷言給定欄位有特定的驗證錯誤訊息
1$response->assertSessionHasErrors([2 'name' => 'The given name was invalid.'3]);
更通用的 assertInvalid 方法可用於斷言響應有作為 JSON 返回的驗證錯誤,或有錯誤快閃記憶體到會話儲存中。
assertSessionHasErrorsIn
斷言會話在特定的錯誤包中包含給定 $keys 的錯誤。如果 $keys 是關聯陣列,則斷言會話對於錯誤包中的每個欄位(鍵)包含特定的錯誤訊息(值)
1$response->assertSessionHasErrorsIn($errorBag, $keys = [], $format = null);
assertSessionHasNoErrors
斷言會話沒有驗證錯誤
1$response->assertSessionHasNoErrors();
assertSessionDoesntHaveErrors
斷言會話對於給定鍵沒有驗證錯誤
1$response->assertSessionDoesntHaveErrors($keys = [], $format = null, $errorBag = 'default');
更通用的 assertValid 方法可用於斷言響應沒有作為 JSON 返回的驗證錯誤,並且沒有錯誤快閃記憶體到會話儲存中。
assertSessionMissing
斷言會話不包含給定的鍵
1$response->assertSessionMissing($key);
assertStatus
斷言響應具有給定的 HTTP 狀態碼
1$response->assertStatus($code);
assertSuccessful
斷言響應具有成功 (>= 200 且 < 300) HTTP 狀態碼
1$response->assertSuccessful();
assertTooManyRequests
斷言響應具有過多請求 (429) HTTP 狀態碼
1$response->assertTooManyRequests();
assertUnauthorized
斷言響應具有未經授權 (401) HTTP 狀態碼
1$response->assertUnauthorized();
assertUnprocessable
斷言響應具有無法處理的實體 (422) HTTP 狀態碼
1$response->assertUnprocessable();
assertUnsupportedMediaType
斷言響應具有不支援的媒體型別 (415) HTTP 狀態碼
1$response->assertUnsupportedMediaType();
assertValid
斷言響應對於給定鍵沒有驗證錯誤。此方法可用於斷言驗證錯誤作為 JSON 結構返回或驗證錯誤已快閃記憶體到會話的響應
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
斷言響應對於給定鍵有驗證錯誤。此方法可用於斷言驗證錯誤作為 JSON 結構返回或驗證錯誤已快閃記憶體到會話的響應
1$response->assertInvalid(['name', 'email']);
你還可以斷言給定鍵有特定的驗證錯誤訊息。執行此操作時,你可以提供完整訊息或訊息的一小部分
1$response->assertInvalid([2 'name' => 'The name field is required.',3 'email' => 'valid email address',4]);
如果你想斷言給定欄位是唯一有驗證錯誤的欄位,可以使用 assertOnlyInvalid 方法
1$response->assertOnlyInvalid(['name', 'email']);
assertViewHas
斷言響應檢視包含給定的資料
1$response->assertViewHas($key, $value = null);
將閉包作為第二個引數傳遞給 assertViewHas 方法,將允許你檢查並對特定檢視資料進行斷言
1$response->assertViewHas('user', function (User $user) {2 return $user->name === 'Taylor';3});
此外,檢視資料可以作為響應物件上的陣列變數進行訪問,從而方便地檢查它
1expect($response['name'])->toBe('Taylor');
1$this->assertEquals('Taylor', $response['name']);
assertViewHasAll
斷言響應檢視具有給定的資料列表
1$response->assertViewHasAll(array $data);
此方法可用於斷言檢視簡單地包含匹配給定鍵的資料
1$response->assertViewHasAll([2 'name',3 'email',4]);
或者,你可以斷言檢視資料存在且具有特定值
1$response->assertViewHasAll([2 'name' => 'Taylor Otwell',4]);
assertViewIs
斷言路由返回了給定的檢視
1$response->assertViewIs($value);
assertViewMissing
斷言給定的資料鍵未提供給應用程式響應中返回的檢視
1$response->assertViewMissing($key);
身份驗證斷言
Laravel 還提供了多種與身份驗證相關的斷言,你可以在應用程式的特性測試中使用。請注意,這些方法是在測試類本身上呼叫的,而不是在 get 和 post 等方法返回的 Illuminate\Testing\TestResponse 例項上呼叫的。
assertAuthenticated
斷言使用者已透過身份驗證
1$this->assertAuthenticated($guard = null);
assertGuest
斷言使用者未透過身份驗證
1$this->assertGuest($guard = null);
assertAuthenticatedAs
斷言特定使用者已透過身份驗證
1$this->assertAuthenticatedAs($user, $guard = null);
驗證斷言
Laravel 提供了兩個主要的與驗證相關的斷言,你可以使用它們來確保請求中提供的資料是有效的或無效的。
assertValid
斷言響應對於給定鍵沒有驗證錯誤。此方法可用於斷言驗證錯誤作為 JSON 結構返回或驗證錯誤已快閃記憶體到會話的響應
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
斷言響應對於給定鍵有驗證錯誤。此方法可用於斷言驗證錯誤作為 JSON 結構返回或驗證錯誤已快閃記憶體到會話的響應
1$response->assertInvalid(['name', 'email']);
你還可以斷言給定鍵有特定的驗證錯誤訊息。執行此操作時,你可以提供完整訊息或訊息的一小部分
1$response->assertInvalid([2 'name' => 'The name field is required.',3 'email' => 'valid email address',4]);