# HTTP 测试
- [介绍](#introduction)
- [自定义请求头](#customizing-request-headers)
- [Cookies](#cookies)
- [调试响应](#debugging-responses)
- [会话/身份验证](#session-and-authentication)
- [测试 JSON API](#testing-json-apis)
- [测试文件上传](#testing-file-uploads)
- [可用断言](#available-assertions)
- [回应断言](#response-assertions)
- [认证断言](#authentication-assertions)
## 介绍
Laravel提供了一个非常流畅的API,用于向您的应用程序发出HTTP请求并检查输出。例如,看一下下面定义的功能测试:
get('/');
$response->assertStatus(200);
}
}
该`get`方法`GET`向应用程序发出请求,而该`assertStatus`方法断言返回的响应应具有给定的HTTP状态代码。除了这个简单的断言之外,Laravel还包含用于检查响应头,内容,JSON结构等的各种断言。
### 自定义请求头
您可以使用此`withHeaders`方法自定义请求的标头,然后再将其发送到应用程序。这使您可以将任何想要的自定义标头添加到请求中:
withHeaders([
'X-Header' => 'Value',
])->json('POST', '/user', ['name' => 'Sally']);
$response
->assertStatus(201)
->assertJson([
'created' => true,
]);
}
}
> {tip} 运行测试时,将自动禁用CSRF中间件。
### 调试响应
测试请求通过应用程序后, `dump` 和 `dumpHeaders` 方法将会在控制台打印响应体和响应头,可以用来分析和调试响应 :
get('/');
$response->dumpHeaders();
$response->dump();
}
}
## Session / 认证
Laravel 提供了几个可在 HTTP 测试时使用 Session 的辅助函数。首先,你需要传递一个数组给 `withSession` 方法来设置 Session 数据。这让你在应用程序的测试请求发送之前,先给数据加载 Session 变得简单:
withSession(['foo' => 'bar'])
->get('/');
}
}
当然,一般使用 Session 时都是用于维护用户状态,如认证用户。`actingAs` 辅助函数提供了简单的方法来指定的用户认证为当前用户。 例如, 我们可以使用 [工厂模型](/docs/{{version}}/database-testing#writing-factories) 来生成并认证用户:
create();
$response = $this->actingAs($user)
->withSession(['foo' => 'bar'])
->get('/');
}
}
你也可以通过传递看守器名称作为`actingAs` 方法的第二参数以指定用户通过哪种看守器来认证:
$this->actingAs($user, 'api')
## 测试 JSON APIs
Laravel 也提供了几个辅助函数来测试 JSON APIs 和他们的响应。 例如,`json`, `get`, `post`, `put`, `patch`,和 `delete` 可以被用于发送各种 HTTP 动作。 你也可以轻松地将数据和请求头传递到这些方法中。让我们写一个 `POST` 请求到 `/user` 并断言返回期望的数据来开始使用他们:
json('POST', '/user', ['name' => 'Sally']);
$response
->assertStatus(201)
->assertJson([
'created' => true,
]);
}
}
> Tip:assertJson 方法将响应转换为数组并利用 PHPUnit::assertArraySubset 来验证给定的数组存在于应用返回的 JSON 响应中。 所以,如果 JSON 响应中有其他属性,测试仍旧会在给定数组存在的情况下通过:
### 验证 JSON 完全匹配
如果你想验证给定的数组 **完全** 匹配应用返回的 JSON 结果,你应该使用 `assertExactJson` 方法:
json('POST', '/user', ['name' => 'Sally']);
$response
->assertStatus(201)
->assertExactJson([
'created' => true,
]);
}
}
### 验证 JSON 路径
如果你想验证 JSON 响应是否包含指定路径上的某些给定数据,则应使用 `assertJsonPath` 方法:
json('POST', '/user', ['name' => 'Sally']);
$response
->assertStatus(201)
->assertJsonPath('team.owner.name', 'foo')
}
}
## 测试文件上传
`Illuminate\Http\UploadedFile` 提供了一个 `fake` 方法用于生成虚拟的文件或者图像以供测试之用。 它可以和 `Storage` facade 的 `fake` 方法相结合, 大幅度简化了文件上传测试。举个例子,你可以结合这两者的功能非常方便地进行头像上传表单测试:
image('avatar.jpg');
$response = $this->json('POST', '/avatar', [
'avatar' => $file,
]);
// Assert the file was stored...
Storage::disk('avatars')->assertExists($file->hashName());
// Assert a file does not exist...
Storage::disk('avatars')->assertMissing('missing.jpg');
}
}
#### 虚拟文件制定
在使用 fake 方法创建文件时,你可以指定图像的宽高以及大小,从而更好的验证测试规则:
UploadedFile::fake()->image('avatar.jpg', $width, $height)->size(100);
除创建图像外,你也可以用 `create` 方法创建其他类型的文件:
UploadedFile::fake()->create('document.pdf', $sizeInKilobytes);
如果需要,可以向该方法传递一个 `$mimeType` 参数,以显式定义文件应返回的 MIME 类型:
UploadedFile::fake()->create('document.pdf', $sizeInKilobytes, 'application/pdf');
## 可用断言方法
### 响应断言
Laravel 给 [PHPUnit](https://phpunit.de/) 测试提供了各种各样的常用断言方法。可从 `json`, `get`, `post`, `put`,和 `delete`测试方法中访问这些断言:
[assertCookie](#assert-cookie)
[assertCookieExpired](#assert-cookie-expired)
[assertCookieNotExpired](#assert-cookie-not-expired)
[assertCookieMissing](#assert-cookie-missing)
[assertCreated](#assert-created)
[assertDontSee](#assert-dont-see)
[assertDontSeeText](#assert-dont-see-text)
[assertExactJson](#assert-exact-json)
[assertForbidden](#assert-forbidden)
[assertHeader](#assert-header)
[assertHeaderMissing](#assert-header-missing)
[assertJson](#assert-json)
[assertJsonCount](#assert-json-count)
[assertJsonFragment](#assert-json-fragment)
[assertJsonMissing](#assert-json-missing)
[assertJsonMissingExact](#assert-json-missing-exact)
[assertJsonMissingValidationErrors](#assert-json-missing-validation-errors)
[assertJsonPath](#assert-json-path)
[assertJsonStructure](#assert-json-structure)
[assertJsonValidationErrors](#assert-json-validation-errors)
[assertLocation](#assert-location)
[assertNoContent](#assert-no-content)
[assertNotFound](#assert-not-found)
[assertOk](#assert-ok)
[assertPlainCookie](#assert-plain-cookie)
[assertRedirect](#assert-redirect)
[assertSee](#assert-see)
[assertSeeInOrder](#assert-see-in-order)
[assertSeeText](#assert-see-text)
[assertSeeTextInOrder](#assert-see-text-in-order)
[assertSessionHas](#assert-session-has)
[assertSessionHasInput](#assert-session-has-input)
[assertSessionHasAll](#assert-session-has-all)
[assertSessionHasErrors](#assert-session-has-errors)
[assertSessionHasErrorsIn](#assert-session-has-errors-in)
[assertSessionHasNoErrors](#assert-session-has-no-errors)
[assertSessionDoesntHaveErrors](#assert-session-doesnt-have-errors)
[assertSessionMissing](#assert-session-missing)
[assertStatus](#assert-status)
[assertSuccessful](#assert-successful)
[assertUnauthorized](#assert-unauthorized)
[assertViewHas](#assert-view-has)
[assertViewHasAll](#assert-view-has-all)
[assertViewIs](#assert-view-is)
[assertViewMissing](#assert-view-missing)
#### assertCookie
断言响应中包含给定的 cookie:
$response->assertCookie($cookieName, $value = null);
#### assertCookieExpired
断言响应中包含了给定的 cookie 且它已过期:
$response->assertCookieExpired($cookieName);
#### assertCookieNotExpired
断言响应中包含了给定的 cookie 且它未过期:
$response->assertCookieNotExpired($cookieName);
#### assertCookieMissing
断言响应中不包含给定的 cookie:
$response->assertCookieMissing($cookieName);
#### assertCreated
断言该响应具有 201 状态码:
$response->assertCreated();
#### assertDontSee
断言响应中不包含给定的字符串:
$response->assertDontSee($value);
#### assertDontSeeText
断言给定字符串不包含在响应文本中:
$response->assertDontSeeText($value);
#### assertExactJson
断言响应中包含的数据与给定的 JSON 数据完全匹配:
$response->assertExactJson(array $data);
#### assertForbidden
断言响应中有禁止状态码:
$response->assertForbidden();
#### assertHeader
断言响应中有给定的 header 头:
$response->assertHeader($headerName, $value = null);
#### assertHeaderMissing
断言响应中没有给定的 header 头:
$response->assertHeaderMissing($headerName);
#### assertJson
断言响应包含给定的 JSON 数据:
$response->assertJson(array $data, $strict = false);
#### assertJsonCount
断言响应 JSON 中有一个数组,其中包含给定键的预期元素数量:
$response->assertJsonCount($count, $key = null);
#### assertJsonFragment
断言响应包含给定 JSON 片段:
$response->assertJsonFragment(array $data);
#### assertJsonMissing
断言响应未包含给定的 JSON 片段:
$response->assertJsonMissing(array $data);
#### assertJsonMissingExact
断言响应不包含确切的 JSON 片段:
$response->assertJsonMissingExact(array $data);
#### assertJsonMissingValidationErrors
断言响应没有给定键的 JSON 验证错误:
$response->assertJsonMissingValidationErrors($keys);
#### assertJsonPath
断言响应包含指定路径上的给定数据:
$response->assertJsonPath($path, array $data, $strict = false);
#### assertJsonStructure
断言响应具有给定的 JSON 结构:
$response->assertJsonStructure(array $structure);
#### assertJsonValidationErrors
断言响应具有给定键的给定 JSON 验证错误:
$response->assertJsonValidationErrors(array $data);
#### assertLocation
断言响应在 `Location` 头部中具有给定的 URI 值:
$response->assertLocation($uri);
#### assertNoContent
断言响应具有给定的状态码,没有内容。
$response->assertNoContent($status = 204);
#### assertNotFound
断言响应具有未找到状态码:
$response->assertNotFound();
#### assertOk
断言响应有 200 状态码:
$response->assertOk();
#### 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);
#### assertSessionHasInput
断言 session 中有给定值数组:
$response->assertSessionHasInput($key, $value = null);
#### assertSessionHasAll
断言 session 中有给定值列表:
$response->assertSessionHasAll(array $data);
#### assertSessionHasErrors
断言该 session 包含给定 `$keys` 的错误。 如果 `$keys` 是一个关联数组,则断言该 session 包含每个字段(键)的特定错误消息(值):
$response->assertSessionHasErrors(array $keys, $format = null, $errorBag = 'default');
#### assertSessionHasErrorsIn
断言该 session 在特定错误包中包含给定 `$keys` 的错误。 如果 `$keys` 是一个关联数组,则断言该会话在错误包内包含每个字段(键)的特定错误消息(值):
$response->assertSessionHasErrorsIn($errorBag, $keys = [], $format = null);
#### assertSessionHasNoErrors
断言 session 没有错误:
$response->assertSessionHasNoErrors();
#### assertSessionDoesntHaveErrors
断言 session 没有给定键错误:
$response->assertSessionDoesntHaveErrors($keys = [], $format = null, $errorBag = 'default');
#### assertSessionMissing
断言 session 中不包含给定键:
$response->assertSessionMissing($key);
#### assertStatus
断言响应中具有给定的状态码:
$response->assertStatus($code);
#### assertSuccessful
断言响应中有成功 (>= 200 and < 300) 的状态码:
$response->assertSuccessful();
#### assertUnauthorized
断言响应中有未授权的(401)状态码:
$response->assertUnauthorized();
#### assertViewHas
断言响应视图是一段给定的数据:
$response->assertViewHas($key, $value = null);
另外,视图数据可以作为数组变量访问:
$this->assertEquals('Taylor', $response['name']);
#### assertViewHasAll
断言响应视图具有给定的数据列表:
$response->assertViewHasAll(array $data);
#### assertViewIs
断言路由返回给定的视图:
$response->assertViewIs($value);
#### assertViewMissing
断言响应视图缺少一段绑定数据:
$response->assertViewMissing($key);
### Authentication Assertions
Laravel 还为你的 [PHPUnit](https://phpunit.de/) 测试提供了各种与身份验证相关的断言:
Method | Description
------------- | -------------
`$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);` | 断言给定的凭证无效。