Appearance
HTTP 测试
介绍
Laravel 提供了一个非常流畅的 API,用于向应用程序发出 HTTP 请求并检查响应。例如,请看一下下面定义的功能测试:
php
<?php
test('the application returns a successful response', function () {
$response = $this->get('/');
$response->assertStatus(200);
});
php
<?php
namespace Tests\Feature;
use Tests\TestCase;
class ExampleTest extends TestCase
{
/**
* 一个基本的测试示例
*/
public function test_the_application_returns_a_successful_response(): void
{
$response = $this->get('/');
$response->assertStatus(200);
}
}
get
方法向应用程序发出 GET
请求,而 assertStatus
方法断言返回的响应应具有给定的 HTTP 状态代码。除了这个简单的断言之外,Laravel 还包含各种用于检查响应标头、内容、JSON 结构等的断言。
提出请求
要向您的应用程序发出请求,您可以在测试中调用 get
、post
、put
、patch
或 delete
方法。这些方法实际上不会向您的应用程序发出“真正的”HTTP 请求。相反,整个网络请求是在内部模拟的。
测试请求方法不是返回 Illuminate\Http\Response
实例,而是返回 Illuminate\Testing\TestResponse
的实例,它提供了各种有用的断言,允许您检查应用程序的响应:
php
<?php
test('basic request', function () {
$response = $this->get('/');
$response->assertStatus(200);
});
php
<?php
namespace Tests\Feature;
use Tests\TestCase;
class ExampleTest extends TestCase
{
/**
* A basic test example.
*/
public function test_a_basic_request(): void
{
$response = $this->get('/');
$response->assertStatus(200);
}
}
通常,每个测试都应只向应用程序发出一个请求。如果在单个测试方法中执行多个请求,则可能会发生意外行为。
NOTE
为方便起见,CSRF中间件在运行测试时会自动禁用。
自定义请求标头
在将请求发送到应用程序之前,您可以使用 withHeaders
方法自定义请求的标头。此方法允许您向请求添加所需的任何自定义标头:
php
<?php
test('interacting with headers', function () {
$response = $this->withHeaders([
'X-Header' => 'Value',
])->post('/user', ['name' => 'Sally']);
$response->assertStatus(201);
});
php
<?php
namespace Tests\Feature;
use Tests\TestCase;
class ExampleTest extends TestCase
{
/**
* A basic functional test example.
*/
public function test_interacting_with_headers(): void
{
$response = $this->withHeaders([
'X-Header' => 'Value',
])->post('/user', ['name' => 'Sally']);
$response->assertStatus(201);
}
}
Cookies
在发出请求之前,您可以使用 withCookie
或 withCookies
方法来设置 cookie 值。withCookie
方法接受 cookie 名称和值作为其两个参数,而 withCookies
方法接受名称/值对数组:
php
<?php
test('interacting with cookies', function () {
$response = $this->withCookie('color', 'blue')->get('/');
$response = $this->withCookies([
'color' => 'blue',
'name' => 'Taylor',
])->get('/');
//
});
php
<?php
namespace Tests\Feature;
use Tests\TestCase;
class ExampleTest extends TestCase
{
public function test_interacting_with_cookies(): void
{
$response = $this->withCookie('color', 'blue')->get('/');
$response = $this->withCookies([
'color' => 'blue',
'name' => 'Taylor',
])->get('/');
//
}
}
会话 / 身份验证
Laravel 提供了几个帮助程序,用于在 HTTP 测试期间与会话进行交互。首先,你可以使用 withSession
方法将会话数据设置为给定的数组。这对于在向应用程序发出请求之前加载包含数据的会话非常有用:
php
<?php
test('interacting with the session', function () {
$response = $this->withSession(['banned' => false])->get('/');
//
});
php
<?php
namespace Tests\Feature;
use Tests\TestCase;
class ExampleTest extends TestCase
{
public function test_interacting_with_the_session(): void
{
$response = $this->withSession(['banned' => false])->get('/');
//
}
}
Laravel 的会话通常用于维护当前已验证用户的状态。因此, actingAs
帮助程序方法提供了一种简单的方法,用于将给定用户验证为当前用户。例如,我们可以使用模型工厂来生成和验证用户:
php
<?php
use App\Models\User;
test('an action that requires authentication', function () {
$user = User::factory()->create();
$response = $this->actingAs($user)
->withSession(['banned' => false])
->get('/');
//
});
php
<?php
namespace Tests\Feature;
use App\Models\User;
use Tests\TestCase;
class ExampleTest extends TestCase
{
public function test_an_action_that_requires_authentication(): void
{
$user = User::factory()->create();
$response = $this->actingAs($user)
->withSession(['banned' => false])
->get('/');
//
}
}
你也可以通过将守卫名称作为第二个参数传递给 actingAs
方法来指定应该使用哪个守卫来验证给定用户。提供给 actingAs
方法的守卫也将成为测试期间的默认守卫:
$this->actingAs($user, 'web')
调试响应
向应用程序发出测试请求后,可以使用 dump``、dumpHeaders
和 dumpSession
方法来检查和调试响应内容:
php
<?php
test('basic test', function () {
$response = $this->get('/');
$response->dumpHeaders();
$response->dumpSession();
$response->dump();
});
php
<?php
namespace Tests\Feature;
use Tests\TestCase;
class ExampleTest extends TestCase
{
/**
* A basic test example.
*/
public function test_basic_test(): void
{
$response = $this->get('/');
$response->dumpHeaders();
$response->dumpSession();
$response->dump();
}
}
或者,您可以使用 dd
、ddHeaders
和 ddSession
方法来转储有关响应的信息,然后停止执行:
php
<?php
test('basic test', function () {
$response = $this->get('/');
$response->ddHeaders();
$response->ddSession();
$response->dd();
});
php
<?php
namespace Tests\Feature;
use Tests\TestCase;
class ExampleTest extends TestCase
{
/**
* A basic test example.
*/
public function test_basic_test(): void
{
$response = $this->get('/');
$response->ddHeaders();
$response->ddSession();
$response->dd();
}
}
异常处理
有时,您可能需要测试应用程序是否引发了特定异常。为此,您可以通过 Exceptions
Facade “伪造” 异常处理程序。伪造异常处理程序后,您可以利用 assertReported
和 assertNotReported
方法对请求期间引发的异常进行断言:
php
<?php
use App\Exceptions\InvalidOrderException;
use Illuminate\Support\Facades\Exceptions;
test('exception is thrown', function () {
Exceptions::fake();
$response = $this->get('/order/1');
// Assert an exception was thrown...
Exceptions::assertReported(InvalidOrderException::class);
// Assert against the exception...
Exceptions::assertReported(function (InvalidOrderException $e) {
return $e->getMessage() === 'The order was invalid.';
});
});
php
<?php
namespace Tests\Feature;
use App\Exceptions\InvalidOrderException;
use Illuminate\Support\Facades\Exceptions;
use Tests\TestCase;
class ExampleTest extends TestCase
{
/**
* A basic test example.
*/
public function test_exception_is_thrown(): void
{
Exceptions::fake();
$response = $this->get('/');
// Assert an exception was thrown...
Exceptions::assertReported(InvalidOrderException::class);
// Assert against the exception...
Exceptions::assertReported(function (InvalidOrderException $e) {
return $e->getMessage() === 'The order was invalid.';
});
}
}
assertNotReported
和 assertNothingReported
方法可用于断言在请求期间未引发给定异常或未引发异常:
php
Exceptions::assertNotReported(InvalidOrderException::class);
Exceptions::assertNothingReported();
您可以通过在发出请求之前调用 withoutExceptionHandling
方法来完全禁用给定请求的异常处理:
php
$response = $this->withoutExceptionHandling()->get('/');
此外,如果您想确保您的应用程序没有利用 PHP 语言或应用程序正在使用的库已弃用的功能,您可以在发出请求之前调用 withoutDeprecationHandling
方法。禁用弃用处理后,弃用警告将转换为异常,从而导致测试失败:
php
$response = $this->withoutDeprecationHandling()->get('/');
assertThrows
方法可用于断言给定闭包中的代码会引发指定类型的异常:
php
$this->assertThrows(
fn () => (new ProcessOrder)->execute(),
OrderInvalid::class
);
如果你想检查并针对抛出的异常进行断言,你可以提供一个闭包作为 assertThrows
方法的第二个参数:
php
$this->assertThrows(
fn () => (new ProcessOrder)->execute(),
fn (OrderInvalid $e) => $e->orderId() === 123;
);
测试 JSON API
Laravel 还提供了几个用于测试 JSON API 及其响应的帮助程序。例如,json
、getJson
、postJson
、putJson
、patchJson
、deleteJson
和 optionsJson
方法可用于发出包含各种 HTTP 动词的 JSON 请求。你也可以轻松地将数据和标头传递给这些方法。首先,让我们编写一个测试来向 /api/user
发出 POST
请求,并断言返回了预期的 JSON 数据:
php
<?php
test('making an api request', function () {
$response = $this->postJson('/api/user', ['name' => 'Sally']);
$response
->assertStatus(201)
->assertJson([
'created' => true,
]);
});
php
<?php
namespace Tests\Feature;
use Tests\TestCase;
class ExampleTest extends TestCase
{
/**
* A basic functional test example.
*/
public function test_making_an_api_request(): void
{
$response = $this->postJson('/api/user', ['name' => 'Sally']);
$response
->assertStatus(201)
->assertJson([
'created' => true,
]);
}
}
此外,JSON 响应数据可以作为响应的数组变量进行访问,从而方便您检查 JSON 响应中返回的单个值:
php
expect($response['created'])->toBeTrue();
php
$this->assertTrue($response['created']);
NOTE
assertJson
方法将响应转换为数组,以验证给定数组是否存在于应用程序返回的 JSON 响应中。因此,如果 JSON 响应中有其他属性,只要给定片段存在,此测试仍将通过。
断言精确 JSON 匹配
如前所述,assertJson
方法可用于断言 JSON 响应中存在 JSON 片段。如果要验证给定数组是否与应用程序返回的 JSON 完全匹配,则应使用 assertExactJson
方法:
php
<?php
test('asserting an exact json match', function () {
$response = $this->postJson('/user', ['name' => 'Sally']);
$response
->assertStatus(201)
->assertExactJson([
'created' => true,
]);
});
php
<?php
namespace Tests\Feature;
use Tests\TestCase;
class ExampleTest extends TestCase
{
/**
* A basic functional test example.
*/
public function test_asserting_an_exact_json_match(): void
{
$response = $this->postJson('/user', ['name' => 'Sally']);
$response
->assertStatus(201)
->assertExactJson([
'created' => true,
]);
}
}
在 JSON 路径上断言
如果要验证 JSON 响应是否包含指定路径中的给定数据,则应使用 assertJsonPath
方法:
php
<?php
test('asserting a json path value', function () {
$response = $this->postJson('/user', ['name' => 'Sally']);
$response
->assertStatus(201)
->assertJsonPath('team.owner.name', 'Darian');
});
php
<?php
namespace Tests\Feature;
use Tests\TestCase;
class ExampleTest extends TestCase
{
/**
* A basic functional test example.
*/
public function test_asserting_a_json_paths_value(): void
{
$response = $this->postJson('/user', ['name' => 'Sally']);
$response
->assertStatus(201)
->assertJsonPath('team.owner.name', 'Darian');
}
}
assertJsonPath
方法还接受一个闭包,该闭包可用于动态确定断言是否应传递:
$response->assertJsonPath('team.owner.name', fn (string $name) => strlen($name) >= 3);
Fluent JSON 测试
Laravel 还提供了一种流畅地测试应用程序的 JSON 响应的漂亮方法。首先,将闭包传递给 assertJson
方法。此闭包将使用 Illuminate\Testing\Fluent\AssertableJson
一个实例调用,该实例可用于对应用程序返回的 JSON 进行断言。where
方法可用于对 JSON 的特定属性进行断言,而 missing
方法可用于断言 JSON 中缺少特定属性:
php
use Illuminate\Testing\Fluent\AssertableJson;
test('fluent json', function () {
$response = $this->getJson('/users/1');
$response
->assertJson(fn (AssertableJson $json) =>
$json->where('id', 1)
->where('name', 'Victoria Faith')
->where('email', fn (string $email) => str($email)->is('victoria@gmail.com'))
->whereNot('status', 'pending')
->missing('password')
->etc()
);
});
php
use Illuminate\Testing\Fluent\AssertableJson;
/**
* A basic functional test example.
*/
public function test_fluent_json(): void
{
$response = $this->getJson('/users/1');
$response
->assertJson(fn (AssertableJson $json) =>
$json->where('id', 1)
->where('name', 'Victoria Faith')
->where('email', fn (string $email) => str($email)->is('victoria@gmail.com'))
->whereNot('status', 'pending')
->missing('password')
->etc()
);
}
了解 etc 方法
在上面的示例中,你可能已经注意到我们在断言链的末尾调用了 etc
方法。此方法通知 Laravel JSON 对象上可能存在其他属性。如果未使用 etc
方法,则当 JSON 对象上存在您未对其进行断言的其他属性时,测试将失败。
此行为背后的目的是防止您无意中在 JSON 响应中公开敏感信息,方法是强制您对属性显式进行断言或通过 etc
方法显式允许其他属性。
但是,您应该知道,在断言链中不包含 etc
方法并不能确保不会将其他属性添加到嵌套在 JSON 对象中的数组中。etc
方法仅确保在调用 etc
方法的嵌套级别上不存在其他属性。
断言属性存在/缺失
要断言属性存在或不存在,您可以使用 has
和 missing
方法:
php
$response->assertJson(fn (AssertableJson $json) =>
$json->has('data')
->missing('message')
);
此外,hasAll
和 missingAll
方法允许同时断言多个属性的存在或不存在:
php
$response->assertJson(fn (AssertableJson $json) =>
$json->hasAll(['status', 'data'])
->missingAll(['message', 'code'])
);
您可以使用 hasAny
方法来确定是否存在给定属性列表中的至少一个:
php
$response->assertJson(fn (AssertableJson $json) =>
$json->has('status')
->hasAny('data', 'message', 'code')
);
针对 JSON 集合进行断言
通常,您的路由将返回包含多个项目(例如多个用户)的 JSON 响应:
php
Route::get('/users', function () {
return User::all();
});
在这些情况下,我们可以使用 Fluent JSON 对象的 has
方法对响应中包含的用户进行断言。例如,让我们断言 JSON 响应包含三个用户。接下来,我们将使用第一种方法
对集合中的第一个用户进行一些断言。第一个
方法接受一个闭包,该闭包接收另一个可断言的 JSON 字符串,我们可以使用它来对 JSON 集合中的第一个对象进行断言:
php
$response
->assertJson(fn (AssertableJson $json) =>
$json->has(3)
->first(fn (AssertableJson $json) =>
$json->where('id', 1)
->where('name', 'Victoria Faith')
->where('email', fn (string $email) => str($email)->is('victoria@gmail.com'))
->missing('password')
->etc()
)
);
界定 JSON 集合断言的范围
有时,应用程序的路由将返回分配了命名键的 JSON 集合:
php
Route::get('/users', function () {
return [
'meta' => [...],
'users' => User::all(),
];
})
在测试这些路由时,你可以使用 has
方法来断言集合中的项目数。此外,你可以使用 has
方法来限定一系列断言的范围:
php
$response
->assertJson(fn (AssertableJson $json) =>
$json->has('meta')
->has('users', 3)
->has('users.0', fn (AssertableJson $json) =>
$json->where('id', 1)
->where('name', 'Victoria Faith')
->where('email', fn (string $email) => str($email)->is('victoria@gmail.com'))
->missing('password')
->etc()
)
);
但是,您可以进行一次调用,将闭包作为其第三个参数,而不是对 has
方法进行两次单独的调用来断言 users
集合。这样做时,闭包将被自动调用,并将范围限定为集合中的第一项:
php
$response
->assertJson(fn (AssertableJson $json) =>
$json->has('meta')
->has('users', 3, fn (AssertableJson $json) =>
$json->where('id', 1)
->where('name', 'Victoria Faith')
->where('email', fn (string $email) => str($email)->is('victoria@gmail.com'))
->missing('password')
->etc()
)
);
断言 JSON 类型
您可能只想断言 JSON 响应中的属性属于特定类型。该 Illuminate\Testing\Fluent\AssertableJson
类提供了 whereType
和 whereAllType
方法来执行此操作:
php
$response->assertJson(fn (AssertableJson $json) =>
$json->whereType('id', 'integer')
->whereAllType([
'users.0.name' => 'string',
'meta' => 'array'
])
);
您可以使用 |
字符指定多个类型,或者将类型数组作为第二个参数传递给 whereType
方法。如果响应值是列出的任何类型,则断言将成功:
php
$response->assertJson(fn (AssertableJson $json) =>
$json->whereType('name', 'string|null')
->whereType('id', ['string', 'integer'])
);
whereType
和 whereAllType
方法可识别以下类型:string
、integer
、double
、boolean
、array
和 null
。
测试文件上传
Illuminate\Http\UploadedFile
类提供了一个 fake
方法,可用于生成用于测试的虚拟文件或图像。这与 Storage
Facade的 fake
方法相结合,大大简化了文件上传的测试。例如,您可以结合这两个功能来轻松测试头像上传表单:
php
<?php
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
test('avatars can be uploaded', function () {
Storage::fake('avatars');
$file = UploadedFile::fake()->image('avatar.jpg');
$response = $this->post('/avatar', [
'avatar' => $file,
]);
Storage::disk('avatars')->assertExists($file->hashName());
});
php
<?php
namespace Tests\Feature;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Tests\TestCase;
class ExampleTest extends TestCase
{
public function test_avatars_can_be_uploaded(): void
{
Storage::fake('avatars');
$file = UploadedFile::fake()->image('avatar.jpg');
$response = $this->post('/avatar', [
'avatar' => $file,
]);
Storage::disk('avatars')->assertExists($file->hashName());
}
}
如果你想断言给定文件不存在,你可以使用 Storage
Facade提供的 assertMissing
方法:
php
Storage::fake('avatars');
// ...
Storage::disk('avatars')->assertMissing('missing.jpg');
测试文件定制
使用 UploadedFile
类提供的 fake
方法创建文件时,您可以指定图像的宽度、高度和大小(以 KB 为单位),以便更好地测试应用程序的验证规则:
php
UploadedFile::fake()->image('avatar.jpg', $width, $height)->size(100);
除了创建图像之外,您还可以使用 create
方法创建任何其他类型的文件:
php
UploadedFile::fake()->create('document.pdf', $sizeInKilobytes);
如果需要,你可以将 $mimeType
参数传递给方法,以显式定义文件应返回的 MIME 类型:
php
UploadedFile::fake()->create(
'document.pdf', $sizeInKilobytes, 'application/pdf'
);
测试视图
Laravel 还允许您渲染视图,而无需向应用程序发出模拟 HTTP 请求。为此,您可以在测试中调用 view
方法。view
方法接受视图名称和可选的数据数组。该方法返回 Illuminate\Testing\TestView
的实例,该实例提供了多种方法来方便地对视图的内容进行断言:
php
<?php
test('a welcome view can be rendered', function () {
$view = $this->view('welcome', ['name' => 'Taylor']);
$view->assertSee('Taylor');
});
php
<?php
namespace Tests\Feature;
use Tests\TestCase;
class ExampleTest extends TestCase
{
public function test_a_welcome_view_can_be_rendered(): void
{
$view = $this->view('welcome', ['name' => 'Taylor']);
$view->assertSee('Taylor');
}
}
TestView
类提供以下断言方法:assertSee
、assertSeeInOrder
、assertSeeText
、assertSeeTextInOrder
、assertDontSee
和 assertDontSeeText
。
如果需要,你可以通过将 TestView
实例强制转换为字符串来获取原始的、渲染的视图内容:
php
$contents = (string) $this->view('welcome');
共享错误
某些视图可能依赖于 Laravel 提供的全局错误包中共享的错误。要用错误消息激活错误包,您可以使用 withViewErrors
方法:
php
$view = $this->withViewErrors([
'name' => ['Please provide a valid name.']
])->view('form');
$view->assertSee('Please provide a valid name.');
渲染 Blade 和组件
如有必要,您可以使用 blade
方法计算和渲染原始 Blade 字符串。与 view
方法一样,blade
方法返回 Illuminate\Testing\TestView
的实例:
php
$view = $this->blade(
'<x-component :name="$name" />',
['name' => 'Taylor']
);
$view->assertSee('Taylor');
您可以使用 component
方法对 Blade 组件进行评估和渲染。component
方法返回 Illuminate\Testing\TestComponent
:
php
$view = $this->component(Profile::class, ['name' => 'Taylor']);
$view->assertSee('Taylor');
可用断言
响应断言
Laravel Illuminate\Testing\TestResponse
的类提供了多种自定义断言方法,您可以在测试应用程序时使用这些方法。可以在 json
、get
、post
、put
和 delete
测试方法返回的响应上访问这些断言:
assertAcceptedassertBadRequestassertConflictassertCookieassertCookieExpiredassertCookieNotExpiredassertCookieMissingassertCreatedassertDontSeeassertDontSeeTextassertDownloadassertExactJsonassertExactJsonStructureassertForbiddenassertFoundassertGoneassertHeaderassertHeaderMissingassertInternalServerErrorassertJsonassertJsonCountassertJsonFragmentassertJsonIsArrayassertJsonIsObjectassertJsonMissingassertJsonMissingExactassertJsonMissingValidationErrorsassertJsonPathassertJsonMissingPathassertJsonStructureassertJsonValidationErrorsassertJsonValidationErrorForassertLocationassertMethodNotAllowedassertMovedPermanentlyassertContentassertNoContentassertStreamedContentassertNotFoundassertOkassertPaymentRequiredassertPlainCookieassertRedirectassertRedirectContainsassertRedirectToRouteassertRedirectToSignedRouteassertRequestTimeoutassertSeeassertSeeInOrderassertSeeTextassertSeeTextInOrderassertServerErrorassertServiceUnavailableassertSessionHasassertSessionHasInputassertSessionHasAllassertSessionHasErrorsassertSessionHasErrorsInassertSessionHasNoErrorsassertSessionDoesntHaveErrorsassertSessionMissingassertStatusassertSuccessfulassertTooManyRequestsassertUnauthorizedassertUnprocessableassertUnsupportedMediaTypeassertValidassertInvalidassertViewHasassertViewHasAllassertViewIsassertViewMissing
assertBadRequest
断言响应具有错误的请求 (400) HTTP 状态代码:
php
$response->assertBadRequest();
assertAccepted
断言响应具有已接受的 (202) HTTP 状态代码:
php
$response->assertAccepted();
assertConflict
断言响应具有冲突 (409) HTTP 状态代码:
php
$response->assertConflict();
assertCookie
断言响应包含给定的 Cookie:
php
$response->assertCookie($cookieName, $value = null);
assertCookieExpired
断言响应包含给定的 cookie 并且它已过期:
php
$response->assertCookieExpired($cookieName);
assertCookieNotExpired
断言响应包含给定的 cookie 并且它未过期:
php
$response->assertCookieNotExpired($cookieName);
assertCookieMissing
断言响应不包含给定的 cookie:
php
$response->assertCookieMissing($cookieName);
assertCreated
断言响应具有 201 HTTP 状态代码:
php
$response->assertCreated();
assertDontSee
断言给定的字符串不包含在应用程序返回的响应中。此断言将自动转义给定的字符串,除非你传递第二个参数 false
:
php
$response->assertDontSee($value, $escaped = true);
assertDontSeeText
断言给定的字符串不包含在响应文本中。此断言将自动转义给定的字符串,除非你传递第二个参数 false
。该方法会在进行断言之前将响应内容传递给 strip_tags
PHP 函数:
php
$response->assertDontSeeText($value, $escaped = true);
assertDownload
断言响应是 “download”。通常,这意味着返回响应的调用路由返回 Response::download
响应、BinaryFileResponse
或 Storage::download
响应:
php
$response->assertDownload();
如果您愿意,您可以断言可下载文件已分配给定的文件名:
php
$response->assertDownload('image.jpg');
assertExactJson
断言响应包含给定 JSON 数据的完全匹配项:
php
$response->assertExactJson(array $data);
assertExactJsonStructure
断言响应包含与给定 JSON 结构完全匹配:
php
$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
断言响应具有禁止 (403) HTTP 状态代码:
php
$response->assertForbidden();
assertFound
断言响应具有找到的 (302) HTTP 状态代码:
php
$response->assertFound();
assertGone
断言响应已消失 (410) HTTP 状态代码:
php
$response->assertGone();
assertHeader
断言响应中存在给定的标头和值:
php
$response->assertHeader($headerName, $value = null);
assertHeaderMissing
断言响应中不存在给定的标头:
php
$response->assertHeaderMissing($headerName);
assertInternalServerError
断言响应具有“内部服务器错误”(500) HTTP 状态代码:
php
$response->assertInternalServerError();
assertJson
断言响应包含给定的 JSON 数据:
php
$response->assertJson(array $data, $strict = false);
assertJson
方法将响应转换为数组,以验证给定数组是否存在于应用程序返回的 JSON 响应中。因此,如果 JSON 响应中有其他属性,只要给定片段存在,此测试仍将通过。
assertJsonCount
断言响应 JSON 具有一个数组,其中包含给定键处的预期项目数:
php
$response->assertJsonCount($count, $key = null);
assertJsonFragment
断言响应在响应中的任意位置包含给定的 JSON 数据:
php
Route::get('/users', function () {
return [
'users' => [
[
'name' => 'Taylor Otwell',
],
],
];
});
$response->assertJsonFragment(['name' => 'Taylor Otwell']);
assertJsonIsArray
断言响应 JSON 是一个数组:
php
$response->assertJsonIsArray();
assertJsonIsObject
断言响应 JSON 是一个对象:
php
$response->assertJsonIsObject();
assertJsonMissing
断言响应不包含给定的 JSON 数据:
php
$response->assertJsonMissing(array $data);
assertJsonMissingExact
断言响应不包含确切的 JSON 数据:
php
$response->assertJsonMissingExact(array $data);
assertJsonMissingValidationErrors
断言响应没有给定键的 JSON 验证错误:
php
$response->assertJsonMissingValidationErrors($keys);
NOTE
更通用的 assertValid 方法可用于断言响应没有作为 JSON 返回的验证错误,并且没有错误被刷入会话存储。
assertJsonPath
断言响应包含指定路径处的给定数据:
php
$response->assertJsonPath($path, $expectedValue);
例如,如果您的应用程序返回以下 JSON 响应:
json
{
"user": {
"name": "Steve Schoger"
}
}
您可以断言 user
对象的 name
属性与给定值匹配,如下所示:
php
$response->assertJsonPath('user.name', 'Steve Schoger');
assertJsonMissingPath
断言响应不包含给定的路径:
php
$response->assertJsonMissingPath($path);
例如,如果您的应用程序返回以下 JSON 响应:
json
{
"user": {
"name": "Steve Schoger"
}
}
您可以断言它不包含 user
对象的 email
属性:
php
$response->assertJsonMissingPath('user.email');
assertJsonStructure
断言响应具有给定的 JSON 结构:
php
$response->assertJsonStructure(array $structure);
例如,如果您的应用程序返回的 JSON 响应包含以下数据
json
{
"user": {
"name": "Steve Schoger"
}
}
您可以断言 JSON 结构符合您的期望,如下所示:
php
$response->assertJsonStructure([
'user' => [
'name',
]
]);
有时,应用程序返回的 JSON 响应可能包含对象数组:
json
{
"user": [
{
"name": "Steve Schoger",
"age": 55,
"location": "Earth"
},
{
"name": "Mary Schoger",
"age": 60,
"location": "Earth"
}
]
}
在这种情况下,您可以使用 *
字符对数组中所有对象的结构进行断言:
php
$response->assertJsonStructure([
'user' => [
'*' => [
'name',
'age',
'location'
]
]
]);
assertJsonValidationErrors
断言响应具有给定键的给定 JSON 验证错误。在对验证错误作为 JSON 结构返回而不是闪写到会话的响应进行断言时,应使用此方法:
php
$response->assertJsonValidationErrors(array $data, $responseKey = 'errors');
NOTE
更通用的 assertInvalid 方法可用于断言响应具有以 JSON 形式返回的验证错误**,或者**错误已刷入会话存储。
assertJsonValidationErrorFor
断言响应包含给定键的任何 JSON 验证错误:
php
$response->assertJsonValidationErrorFor(string $key, $responseKey = 'errors');
assertMethodNotAllowed
断言响应具有不允许的方法 (405) HTTP 状态代码:
php
$response->assertMethodNotAllowed();
assertMovedPermanently
断言响应具有永久移动 (301) HTTP 状态代码:
php
$response->assertMovedPermanently();
assertLocation
断言响应在 Location
标头中具有给定的 URI 值:
php
$response->assertLocation($uri);
assertContent
断言给定的字符串与响应内容匹配:
php
$response->assertContent($value);
assertNoContent
断言响应具有给定的 HTTP 状态代码且没有内容:
php
$response->assertNoContent($status = 204);
assertStreamedContent
断言给定的字符串与流式响应内容匹配:
php
$response->assertStreamedContent($value);
assertNotFound
断言响应具有未找到 (404) HTTP 状态代码:
php
$response->assertNotFound();
assertOk
断言响应具有 200 HTTP 状态代码:
php
$response->assertOk();
assertPaymentRequired
断言响应具有需要付款 (402) HTTP 状态代码:
php
$response->assertPaymentRequired();
assertPlainCookie
断言响应包含给定的未加密 Cookie:
php
$response->assertPlainCookie($cookieName, $value = null);
assertRedirect
断言响应是指向给定 URI 的重定向:
php
$response->assertRedirect($uri = null);
assertRedirectContains
断言响应是否重定向到包含给定字符串的 URI:
php
$response->assertRedirectContains($string);
assertRedirectToRoute
断言响应是指向给定命名路由的重定向:
php
$response->assertRedirectToRoute($name, $parameters = []);
assertRedirectToSignedRoute
断言响应是指向给定签名路由的重定向:
php
$response->assertRedirectToSignedRoute($name = null, $parameters = []);
assertRequestTimeout
断言响应具有请求超时 (408) HTTP 状态代码:
php
$response->assertRequestTimeout();
assertSee
断言给定字符串包含在响应中。此断言将自动转义给定的字符串,除非你传递第二个参数 false
:
php
$response->assertSee($value, $escaped = true);
assertSeeInOrder
断言给定的字符串在响应中按顺序包含。此断言将自动转义给定的字符串,除非你传递第二个参数 false
:
php
$response->assertSeeInOrder(array $values, $escaped = true);
assertSeeText
断言给定的字符串包含在响应文本中。此断言将自动转义给定的字符串,除非你传递第二个参数 false
。在进行断言之前,响应内容将传递给 strip_tags
PHP 函数:
php
$response->assertSeeText($value, $escaped = true);
assertSeeTextInOrder
断言给定的字符串在响应文本中按顺序包含。此断言将自动转义给定的字符串,除非你传递第二个参数 false
。在进行断言之前,响应内容将传递给 strip_tags
PHP 函数:
php
$response->assertSeeTextInOrder(array $values, $escaped = true);
assertServerError
断言响应具有服务器错误(>= 500、< 600)HTTP 状态代码:
php
$response->assertServerError();
assertServiceUnavailable
断言响应具有 “Service Unavailable” (503) HTTP 状态代码:
php
$response->assertServiceUnavailable();
assertSessionHas
断言会话包含给定的数据:
php
$response->assertSessionHas($key, $value = null);
如果需要,可以将闭包作为 assertSessionHas
方法的第二个参数提供。如果闭包返回 true
,则断言将传递:
php
$response->assertSessionHas($key, function (User $value) {
return $value->name === 'Taylor Otwell';
});
assertSessionHasInput
断言会话在 flashed input 数组中具有给定值:
php
$response->assertSessionHasInput($key, $value = null);
如果需要,可以将闭包作为 assertSessionHasInput
方法的第二个参数提供。如果闭包返回 true
,则断言将传递:
php
use Illuminate\Support\Facades\Crypt;
$response->assertSessionHasInput($key, function (string $value) {
return Crypt::decryptString($value) === 'secret';
});
assertSessionHasAll
断言 session 包含给定的键 / 值对数组:
php
$response->assertSessionHasAll(array $data);
例如,如果您的应用程序的会话包含 name
和 status
key,您可以断言两者都存在并具有指定的值,如下所示:
php
$response->assertSessionHasAll([
'name' => 'Taylor Otwell',
'status' => 'active',
]);
assertSessionHasErrors
断言会话包含给定$keys
的错误。如果 $keys
是关联数组,则断言会话包含每个字段 (键) 的特定错误消息 (值) 。在测试将验证错误刷写到会话的路由时,应使用此方法,而不是将它们作为 JSON 结构返回:
php
$response->assertSessionHasErrors(
array $keys = [], $format = null, $errorBag = 'default'
);
例如,要断言 name
和 email
字段具有已闪到会话中的验证错误消息,您可以像这样调用 assertSessionHasErrors
方法:
php
$response->assertSessionHasErrors(['name', 'email']);
或者,您可以断言给定字段具有特定的验证错误消息:
php
$response->assertSessionHasErrors([
'name' => 'The given name was invalid.'
]);
NOTE
更通用的 assertInvalid 方法可用于断言响应具有以 JSON 形式返回的验证错误**,或者**错误已刷入会话存储。
assertSessionHasErrorsIn
断言会话包含特定错误包中给定$keys
的错误。如果 $keys
是一个关联数组,则断言会话在错误包中为每个字段(键)包含一个特定的错误消息(值):
php
$response->assertSessionHasErrorsIn($errorBag, $keys = [], $format = null);
assertSessionHasNoErrors
断言会话没有验证错误:
php
$response->assertSessionHasNoErrors();
assertSessionDoesntHaveErrors
断言会话对给定的键没有验证错误:
php
$response->assertSessionDoesntHaveErrors($keys = [], $format = null, $errorBag = 'default');
NOTE
更通用的 assertValid 方法可用于断言响应没有作为 JSON 返回的验证错误,并且没有错误被刷入会话存储。
assertSessionMissing
断言会话不包含给定的键:
php
$response->assertSessionMissing($key);
assertStatus
断言响应具有给定的 HTTP 状态代码:
php
$response->assertStatus($code);
assertSuccessful
断言响应具有成功(>= 200 和 < 300)HTTP 状态代码:
php
$response->assertSuccessful();
assertTooManyRequests
断言响应具有过多的请求 (429) HTTP 状态代码:
php
$response->assertTooManyRequests();
assertUnauthorized
断言响应具有未经授权的 (401) HTTP 状态代码:
php
$response->assertUnauthorized();
assertUnprocessable
断言响应具有不可处理的实体 (422) HTTP 状态代码:
php
$response->assertUnprocessable();
assertUnsupportedMediaType
断言响应具有不受支持的媒体类型 (415) HTTP 状态代码:
php
$response->assertUnsupportedMediaType();
assertValid
断言响应没有给定键的验证错误。此方法可用于对验证错误作为 JSON 结构返回或验证错误已闪入会话的响应进行断言:
php
// 断言不存在验证错误...
$response->assertValid();
// 断言给定的密钥没有验证错误...
$response->assertValid(['name', 'email']);
assertInvalid
断言响应具有给定键的验证错误。此方法可用于对验证错误作为 JSON 结构返回或验证错误已闪入会话的响应进行断言:
php
$response->assertInvalid(['name', 'email']);
您还可以断言给定的密钥具有特定的验证错误消息。执行此操作时,您可以提供完整的消息或仅提供消息的一小部分:
php
$response->assertInvalid([
'name' => 'The name field is required.',
'email' => 'valid email address',
]);
assertViewHas
断言响应视图包含给定的数据片段:
php
$response->assertViewHas($key, $value = null);
将闭包作为第二个参数传递给 assertViewHas
方法将允许你检查并针对特定的视图数据进行断言:
php
$response->assertViewHas('user', function (User $user) {
return $user->name === 'Taylor';
});
此外,视图数据可以作为响应上的数组变量进行访问,从而可以方便地对其进行检查:
php
expect($response['name'])->toBe('Taylor');
php
$this->assertEquals('Taylor', $response['name']);
assertViewHasAll
断言响应视图具有给定的数据列表:
php
$response->assertViewHasAll(array $data);
此方法可用于断言视图仅包含与给定键匹配的数据:
php
$response->assertViewHasAll([
'name',
'email',
]);
或者,您可以断言视图数据存在且具有特定值:
php
$response->assertViewHasAll([
'name' => 'Taylor Otwell',
'email' => 'taylor@example.com,',
]);
assertViewIs
断言给定的视图是由路由返回的:
php
$response->assertViewIs($value);
assertViewMissing
断言给定的数据键未提供给应用程序响应中返回的视图:
php
$response->assertViewMissing($key);
Authentication Assertions
Laravel 还提供了各种与身份验证相关的断言,您可以在应用程序的功能测试中使用这些断言。请注意,这些方法是在测试类本身上调用的,而不是在 get
和 post
等方法返回的 Illuminate\Testing\TestResponse
实例上调用的。
assertAuthenticated
断言用户已经过身份验证:
php
$this->assertAuthenticated($guard = null);
assertGuest
断言用户未经过身份验证:
php
$this->assertGuest($guard = null);
assertAuthenticatedAs
断言特定用户已经过身份验证:
php
$this->assertAuthenticatedAs($user, $guard = null);
验证断言
Laravel 提供了两个主要的验证相关断言,您可以使用它们来确保请求中提供的数据有效或无效。
assertValid
断言响应没有给定键的验证错误。此方法可用于对验证错误作为 JSON 结构返回或验证错误已闪入会话的响应进行断言:
php
// 断言不存在验证错误...
$response->assertValid();
// 断言给定的密钥没有验证错误...
$response->assertValid(['name', 'email']);
assertInvalid
断言响应具有给定键的验证错误。此方法可用于对验证错误作为 JSON 结构返回或验证错误已闪入会话的响应进行断言:
php
$response->assertInvalid(['name', 'email']);
您还可以断言给定的密钥具有特定的验证错误消息。执行此操作时,您可以提供完整的消息或仅提供消息的一小部分:
php
$response->assertInvalid([
'name' => 'The name field is required.',
'email' => 'valid email address',
]);