# Laravel 測試之:HTTP 測試
- [簡介](#introduction)
- [Session / 認證](#session-and-authentication)
- [測試 JSON APIs](#testing-json-apis)
- [測試文件上傳](#testing-file-uploads)
- [可用的斷言方法](#available-assertions)
<a name="introduction"></a>
## 簡介
Laravel 為 HTTP 請求的生成和輸出的檢查都提供了非常流暢的 API。例如,你可以查看下面的這個測試用例:
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ExampleTest extends TestCase
{
/**
* 一個基礎的測試用例。
*
* @return void
*/
public function testBasicTest()
{
$response = $this->get('/');
$response->assertStatus(200);
}
}
`get` 方法會創建一個 `GET` 請求來請求你的應用,而 `assertStatus` 方法斷言返回的響應是指定的 HTTP 狀態碼。除了這個簡單的斷言之外,Laravel 也包含檢查響應標頭、內容、JSON 結構等各種斷言。
<a name="session-and-authentication"></a>
## Session / 認證
Laravel 提供了幾個可在測試時使用 Session 的輔助函數。首先,你需要傳遞一個數組給 `withSession` 方法來設置 Seesion 數據。這讓你在應用程序的測試請求發送之前,先給數據加載 Session 變得簡單:
<?php
class ExampleTest extends TestCase
{
public function testApplication()
{
$response = $this->withSession(['foo' => 'bar'])
->get('/');
}
}
當然,一般使用 Session 時都是用于維持用戶的狀態,如認證用戶。`actingAs` 輔助函數提供了簡單的方式來讓指定的用戶認證為當前的用戶。例如,我們可以使用 [模型工廠](/docs/{{version}}/database-testing#writing-factories) 來生成并認證用戶:
<?php
use App\User;
class ExampleTest extends TestCase
{
public function testApplication()
{
$user = factory(User::class)->create();
$response = $this->actingAs($user)
->withSession(['foo' => 'bar'])
->get('/');
}
}
你也可以通過傳遞 guard 名稱作為 `actingAs` 的第二參數以指定用戶通過哪種 guard 來認證:
$this->actingAs($user, 'api')
<a name="testing-json-apis"></a>
## Testing JSON APIs
Laravel 也提供了幾個輔助函數來測試 JSON APIs 及其響應。例如,`json`,`get`,`post`,`put`,`patch` 和 `delete` 方法可以用于發出各種 HTTP 動作的請求。你也可以輕松的傳入數據或標頭到這些方法上。首先,讓我們來編寫一個測試,將一個 `POST` 請求發送至 `/user` ,并斷言其會返回預期數據:
<?php
class ExampleTest extends TestCase
{
/**
* 一個基礎的功能測試用例。
*
* @return void
*/
public function testBasicExample()
{
$response = $this->json('POST', '/user', ['name' => 'Sally']);
$response
->assertStatus(200)
->assertJson([
'created' => true,
]);
}
}
> {tip} `assertJson` 方法會將響應轉換為數組并且利用 `PHPUnit::assertArraySubset` 方法來驗證傳入的數組是否在應用返回的 JSON 中。也就是說,即使有其它的屬性存在于該 JSON 響應中,但是只要指定的片段存在,此測試仍然會通過。
<a name="verifying-exact-match"></a>
### 驗證完全匹配
如果你想驗證傳入的數組是否與應用返回的 JSON **完全** 匹配,你可以使用 `assertExactJson` 方法:
<?php
class ExampleTest extends TestCase
{
/**
* 一個基礎的功能測試用例。
*
* @return void
*/
public function testBasicExample()
{
$response = $this->json('POST', '/user', ['name' => 'Sally']);
$response
->assertStatus(200)
->assertExactJson([
'created' => true,
]);
}
}
<a name="testing-file-uploads"></a>
## 測試文件上傳
`Illuminate\Http\UploadedFile` 類提供了一個 `fake` 方法,可用其生成用于測試的模擬文件或圖像。將其與 `Storage` facade 的 `fake` 方法結合使用,可極大地簡化文件上傳的測試。例如,你可以結合這兩個功能輕松測試頭像上傳表單:
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ExampleTest extends TestCase
{
public function testAvatarUpload()
{
Storage::fake('avatars');
$response = $this->json('POST', '/avatar', [
'avatar' => UploadedFile::fake()->image('avatar.jpg')
]);
// 斷言文件已存儲...
Storage::disk('avatars')->assertExists('avatar.jpg');
// 斷言文件不存在...
Storage::disk('avatars')->assertMissing('missing.jpg');
}
}
#### 自定義模擬文件
當使用 `fake` 方法創建文件時,你可以指定圖片的寬度、高度和大小,以便更好地測試你的驗證規則:
UploadedFile::fake()->image('avatar.jpg', $width, $height)->size(100);
除了創建圖片,你還可以使用 `create` 方法創建任何其他類型的文件:
UploadedFile::fake()->create('document.pdf', $sizeInKilobytes);
<a name="available-assertions"></a>
## 可用的斷言方法
Laravel 為你的 [PHPUnit](https://phpunit.de/) 測試提供了各種各樣的自定義斷言方法。`json`,`get`,`post`,`put` 和 `delete` 這些測試方法返回的響應都可以使用這些斷言方法:
Method | Description
------------- | -------------
`$response->assertSuccessful();` | 斷言該響應具有成功的狀態碼。
`$response->assertStatus($code);` | 斷言該響應具有指定的狀態碼。
`$response->assertRedirect($uri);` | 斷言該響應被重定向至指定的 URI。
`$response->assertHeader($headerName, $value = null);` | 斷言該響應存在指定的標頭。
`$response->assertCookie($cookieName, $value = null);` | 斷言該響應包含了指定的 Cookie。
`$response->assertPlainCookie($cookieName, $value = null);` | 斷言該響應包含了指定的 Cookie(未加密)。
`$response->assertSessionHas($key, $value = null);` | 斷言該 Session 包含指定的數據。
`$response->assertSessionHasErrors(array $keys, $errorBag = 'default');` | 斷言該 Session 包含指定的字段的錯誤信息。
`$response->assertSessionMissing($key);` | 斷言該 Session 不包含指定的鍵。
`$response->assertJson(array $data);` | 斷言該響應包含指定的 JSON 數據。
`$response->assertJsonFragment(array $data);` | 斷言該響應包含指定的 JSON 片段。
`$response->assertJsonMissing(array $data);` | 斷言該響應不包含指定的 JSON 片段。
`$response->assertExactJson(array $data);` | 斷言該響應包含完全匹配指定的 JSON 數據。
`$response->assertJsonStructure(array $structure);` | 斷言該響應存在指定的 JSON 結構。
`$response->assertViewIs($value);` | 斷言該視圖響應的視圖名稱為指定的值。
`$response->assertViewHas($key, $value = null);` | 斷言該視圖響應存在指定的數據。
## 譯者署名
| 用戶名 | 頭像 | 職能 | 簽名 |
|---|---|---|---|
| [@springjk](https://laravel-china.org/users/4550) | <img class="avatar-66 rm-style" src="https://dn-phphub.qbox.me/uploads/avatars/4550_1464580958.png?imageView2/1/w/100/h/100"> | 翻譯 | 再怎么說我也是我西北一匹狼 |
---
> {note} 歡迎任何形式的轉載,但請務必注明出處,尊重他人勞動共創開源社區。
>
> 轉載請注明:本文檔由 Laravel China 社區 [laravel-china.org](https://laravel-china.org) 組織翻譯,詳見 [翻譯召集帖](https://laravel-china.org/topics/5756/laravel-55-document-translation-call-come-and-join-the-translation)。
>
> 文檔永久地址: https://d.laravel-china.org
- 說明
- 翻譯說明
- 發行說明
- 升級說明
- 貢獻導引
- 入門指南
- 安裝
- 配置信息
- 文件夾結構
- HomeStead
- Valet
- 核心架構
- 請求周期
- 服務容器
- 服務提供者
- 門面(Facades)
- Contracts
- 基礎功能
- 路由
- 中間件
- CSRF 保護
- 控制器
- 請求
- 響應
- 視圖
- 重定向
- Session
- 表單驗證
- 錯誤與日志
- 前端開發
- Blade 模板
- 本地化
- 前端指南
- 編輯資源 Mix
- 安全
- 用戶認證
- API認證
- 用戶授權
- 加密解密
- 哈希
- 重置密碼
- 綜合話題
- Artisan 命令行
- 廣播系統
- 緩存系統
- 集合
- 事件系統
- 文件存儲
- 輔助函數
- 郵件發送
- 消息通知
- 擴展包開發
- 隊列
- 任務調度
- 數據庫
- 快速入門
- 查詢構造器
- 分頁
- 數據庫遷移
- 數據填充
- Redis
- Eloquent ORM
- 快速入門
- 模型關聯
- Eloquent 集合
- 修改器
- API 資源
- 序列化
- 測試
- 快速入門
- HTTP 測試
- 瀏覽器測試 Dusk
- 數據庫測試
- 測試模擬器
- 官方擴展包
- Cashier 交易工具包
- Envoy 部署工具
- Horizon
- Passport OAuth 認證
- Scout 全文搜索
- Socialite 社交化登錄
- 交流說明