ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
* * * * * [TOC] ## 简介 Laravel 为 HTTP 请求的生成和输出的检查都提供了非常流畅的 API。例如,你可以查看下面的这个测试用例: ~~~ <?php namespace Tests\Feature; use Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\WithoutMiddleware; class ExampleTest extends TestCase { /** * 一个基础的测试用例。 * * @return void */ public function testBasicTest() { $response = $this->get('/'); $response->assertStatus(200); } } ~~~ `get` 方法会创建一个 `GET` 请求来请求你的应用,而 `assertStatus` 方法断言返回的响应是指定的 HTTP 状态码。除了这个简单的断言之外,Laravel 也包含检查响应标头、内容、JSON 结构等各种断言。 ### 自定义请求头 您可以使用 `withHeaders` 方法在发送到应用程序之前自定义请求的标头。 你可以添加想要的任何自定义标题: ~~~ <?php class ExampleTest extends TestCase { /** * 一个基本的功能测试示例。 * * @return void */ public function testBasicExample() { $response = $this->withHeaders([ 'X-Header' => 'Value', ])->json('POST', '/user', ['name' => 'Sally']); $response ->assertStatus(200) ->assertJson([ 'created' => true, ]); } } ~~~ > {tip} 运行测试时,CSRF 中间件会自动禁用。 ## Session / 认证 Laravel 提供了几个可在测试时使用 Session 的辅助函数。首先,你需要传递一个数组给 `withSession` 方法来设置 Seesion 数据。这让你在应用程序的测试请求发送之前,先给数据加载 Session 变得简单: ~~~ <?php class ExampleTest extends TestCase { public function testApplication() { $response = $this->withSession(['foo' => 'bar']) ->get('/'); } } ~~~ 当然,一般使用 Session 时都是用于维持用户的状态,如认证用户。`actingAs` 辅助函数提供了简单的方式来让指定的用户认证为当前的用户。例如,我们可以使用 [工厂模型](https://www.kancloud.cn/tonyyu/laravel_5_6/786284#_68) 来生成并认证用户: ~~~ <?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') ~~~ ## 测试 JSON API Laravel 也提供了几个辅助函数来测试JSON API 和它们的相应。例如 `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 相应中如果有其他属性,测试仍旧会在给定数组存在的情况下通过。 ### 验证完全匹配 如果你想验证应用返回的 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, ]); } } ~~~ ## 测试文件上传 进行测试时,这个 `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\RefreshDatabase; use Illuminate\Foundation\Testing\WithoutMiddleware; 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); ~~~ ## 可用断言 ### 响应断言 `Laravel` 为您的 [PHPUnit](https://phpunit.de/) 测试提供了各种常规断言方法。 这些断言可以通过从 `json`, `get`, `post`, `put`, 和 `delete` 测试方法返回的响应来访问: [assertCookie](#_Cookie_249) [assertCookieExpired](#_Cookie__257) [assertCookieMissing](#_Cookie__265) [assertDontSee](#assertDontSee_273) [assertDontSeeText](#assertDontSeeText_281) [assertExactJson](#assertExactJson_289) [assertHeader](#assertHeader_297) [assertHeaderMissing](#assertHeaderMissing_305) [assertJson](#assertJson_313) [assertJsonFragment](#assertJsonFragment_321) [assertJsonMissing](#assertJsonMissing_329) [assertJsonMissingExact](#assertJsonMissingExact_337) [assertJsonStructure](#assertJsonStructure_345) [assertJsonValidationErrors](#assertJsonValidationErrors_353) [assertPlainCookie](#assertPlainCookie_361) [assertRedirect](#assertRedirect_369) [assertSee](#assertSee_377) [assertSeeInOrder](#assertSeeInOrder_385) [assertSeeText](#assertSeeText_393) [assertSeeTextInOrder](#assertSeeTextInOrder_401) [assertSessionHas](#assertSessionHas_409) [assertSessionHasAll](#assertSessionHasAll_417) [assertSessionHasErrors](#assertSessionHasErrors_425) [assertSessionHasErrorsIn](#assertSessionHasErrorsIn_433) [assertSessionMissing](#assertSessionMissing_441) [assertStatus](#assertStatus_449) [assertSuccessful](#assertSuccessful_457) [assertViewHas](#assertViewHas_465) [assertViewHasAll](#assertViewHasAll_473) [assertViewIs](#assertViewIs_481) [assertViewMissing](#assertViewMissing_489) #### 断言 Cookie 断言此响应包含给定的 `cookie`: ~~~ $response->assertCookie($cookieName, $value = null); ~~~ #### 断言 Cookie 过期 断言此响应包含给定的 `cookie` 并且其已过期: ~~~ $response->assertCookieExpired($cookieName); ~~~ #### 断言 Cookie 丢失 断言此响应不包含给定的 `cookie`: ~~~ $response->assertCookieMissing($cookieName); ~~~ #### assertDontSee 验证所给的字符串不包含在响应中: ~~~ $response->assertDontSee($value); ~~~ #### assertDontSeeText 验证所给的字符串不包含在响应的文本中: ~~~ $response->assertDontSeeText($value); ~~~ #### assertExactJson 验证响应和所给 JSON 数据完全符合: ~~~ $response->assertExactJson(array $data); ~~~ #### assertHeader 验证所给的头目前在响应中: ~~~ $response->assertHeader($headerName, $value = null); ~~~ #### assertHeaderMissing 验证所给的头目前没有在响应中: ~~~ $response->assertHeaderMissing($headerName); ~~~ #### assertJson 验证响应包含所给的 JSON 数据: ~~~ $response->assertJson(array $data); ~~~ #### assertJsonFragment 验证此响应包含给定的 JSON 片段: ~~~ $response->assertJsonFragment(array $data); ~~~ #### assertJsonMissing 验证此响应不包含给定的 JSON 片段: ~~~ $response->assertJsonMissing(array $data); ~~~ #### assertJsonMissingExact 验证此响应不包含确切的 JSON 片段 ~~~ $response->assertJsonMissingExact(array $data); ~~~ #### assertJsonStructure 验证此响应含有给定的 JSON 结构: ~~~ $response->assertJsonStructure(array $structure); ~~~ #### assertJsonValidationErrors 验证此响应有给定键的 JSON 验证错误 : ~~~ $response->assertJsonValidationErrors($keys); ~~~ #### assertPlainCookie 验证此响应包含所给的 cookie 『 加密 』: ~~~ $response->assertPlainCookie($cookieName, $value = null); ~~~ #### assertRedirect 断言响应重定向到指定 URI: ~~~ $response->assertRedirect($uri); ~~~ #### assertSee 断言响应中包含指定字符串: ~~~ $response->assertSee($value); ~~~ #### assertSeeInOrder 断言响应中有序包含指定字符串: ~~~ $response->assertSeeInOrder(array $values); ~~~ #### assertSeeText 断言响应文本中包含指定字符串: ~~~ $response->assertSeeText($value); ~~~ #### assertSeeTextInOrder 断言响应文本中有序包含指定字符串: ~~~ $response->assertSeeTextInOrder(array $values); ~~~ #### assertSessionHas 断言 session 包含数据片段: ~~~ $response->assertSessionHas($key, $value = null); ~~~ #### assertSessionHasAll 断言 session 中存在指定的所有值: ~~~ $response->assertSessionHasAll($key, $value = null); ~~~ #### assertSessionHasErrors 断言 session 中含有指定错误: ~~~ $response->assertSessionHasErrors(array $keys, $format = null, $errorBag = 'default'); ~~~ #### assertSessionHasErrorsIn 断言 session 中含有指定错误: ~~~ $response->assertSessionHasErrorsIn($errorBag, $keys = [], $format = null); ~~~ #### assertSessionMissing 断言 session 中不含有指定键: ~~~ $response->assertSessionMissing($key); ~~~ #### assertStatus 断言响应中存在指定状态码: ~~~ $response->assertStatus($code); ~~~ #### assertSuccessful 断言响应中存在成功状态码: ~~~ $response->assertSuccessful(); ~~~ #### assertViewHas 断言响应视图中存在指定数据片段: ~~~ $response->assertViewHas($key, $value = null); ~~~ #### assertViewHasAll 断言响应视图中存在指定的所有数据: ~~~ $response->assertViewHasAll(array $data); ~~~ #### assertViewIs 断言响应视图与指定值一致: ~~~ $response->assertViewIs($value); ~~~ #### assertViewMissing 断言响应视图缺少一个绑定的数据: ~~~ $response->assertViewMissing($key); ~~~ ### 认证断言 `Laravel` 为您的 [PHPUnit](https://phpunit.de/) 测试提供了多种身份认证相关的断言: | 方法 | 描述 | | --- | --- | | `$this->assertAuthenticated($guard = null);` | 断言此用户已被认证 | | `$this->assertGuest($guard = null);` | 断言此用户未被认证 | | `$this->assertAuthenticatedAs($user, $guard = null);` | 断言给定的用户被认证 | | `$this->assertCredentials(array $credentials, $guard = null);` | 断言给定的凭证有效 | | `$this->assertInvalidCredentials(array $credentials, $guard = null);` | 断言给定的凭证无效 | 本文章首发在