介绍
Laravel 为向您的应用程序发送 HTTP 请求并检查响应提供了一个非常流畅的 API。例如,请看下面定义的功能测试:
<?php
test('应用程序返回成功响应', function () {
$response = $this->get('/');
$response->assertStatus(200);
});
<?php
namespace Tests\Feature;
use Tests\TestCase;
class ExampleTest extends TestCase
{
/**
* 一个基本的测试示例。
*/
public function test_应用程序返回成功响应(): 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
test('基本请求', function () {
$response = $this->get('/');
$response->assertStatus(200);
});
<?php
namespace Tests\Feature;
use Tests\TestCase;
class ExampleTest extends TestCase
{
/**
* 一个基本的测试示例。
*/
public function test_一个基本请求(): void
{
$response = $this->get('/');
$response->assertStatus(200);
}
}
一般来说,您的每个测试应该只向您的应用程序发出一个请求。如果在单个测试方法中执行多个请求,可能会出现意外行为。
[!注意]
为了方便起见,在运行测试时,CSRF 中间件会自动禁用。
自定义请求头
您可以使用withHeaders
方法在将请求发送到应用程序之前自定义请求的头。此方法允许您向请求添加任何您想要的自定义头:
<?php
test('与头交互', function () {
$response = $this->withHeaders([
'X-Header' => 'Value',
])->post('/user', ['name' => 'Sally']);
$response->assertStatus(201);
});
<?php
namespace Tests\Feature;
use Tests\TestCase;
class ExampleTest extends TestCase
{
/**
* 一个基本的功能测试示例。
*/
public function test_与头交互(): void
{
$response = $this->withHeaders([
'X-Header' => 'Value',
])->post('/user', ['name' => 'Sally']);
$response->assertStatus(201);
}
}
Cookie
您可以使用withCookie
或withCookies
方法在发出请求之前设置 Cookie 值。withCookie
方法接受 Cookie 名称和值作为其两个参数,而withCookies
方法接受一个名称/值对的数组:
<?php
test('与 Cookie 交互', function () {
$response = $this->withCookie('color', 'blue')->get('/');
$response = $this->withCookies([
'color' => 'blue',
'name' => 'Taylor',
])->get('/');
//
});
<?php
namespace Tests\Feature;
use Tests\TestCase;
class ExampleTest extends TestCase
{
public function test_与_Cookie_交互(): void
{
$response = $this->withCookie('color', 'blue')->get('/');
$response = $this->withCookies([
'color' => 'blue',
'name' => 'Taylor',
])->get('/');
//
}
}
会话/认证
Laravel 在 HTTP 测试期间为与会话进行交互提供了几个帮助器。首先,您可以使用withSession
方法将会话数据设置为给定的数组。这对于在向应用程序发出请求之前加载会话数据很有用:
<?php
test('与会话交互', function () {
$response = $this->withSession(['banned' => false])->get('/');
//
});
<?php
namespace Tests\Feature;
use Tests\TestCase;
class ExampleTest extends TestCase
{
public function test_与会话交互(): void
{
$response = $this->withSession(['banned' => false])->get('/');
//
}
}
Laravel 的会话通常用于维护当前认证用户的状态。因此,actingAs
帮助器方法提供了一种简单的方法来将给定用户认证为当前用户。例如,我们可以使用模型工厂来生成并认证一个用户:
<?php
use App\Models\User;
test('需要认证的操作', function () {
$user = User::factory()->create();
$response = $this->actingAs($user)
->withSession(['banned' => false])
->get('/');
//
});
<?php
namespace Tests\Feature;
use App\Models\User;
use Tests\TestCase;
class ExampleTest extends TestCase
{
public function test_需要认证的操作(): void
{
$user = User::factory()->create();
$response = $this->actingAs($user)
->withSession(['banned' => false])
->get('/');
//
}
}
您还可以通过将守卫名称作为actingAs
方法的第二个参数来指定应该使用哪个守卫来认证给定的用户。提供给actingAs
方法的守卫也将成为测试期间的默认守卫:
$this->actingAs($user, 'web')
调试响应
在向您的应用程序发出测试请求后,可以使用dump
、dumpHeaders
和dumpSession
方法来检查和调试响应内容:
<?php
test('基本测试', function () {
$response = $this->get('/');
$response->dumpHeaders();
$response->dumpSession();
$response->dump();
});
<?php
namespace Tests\Feature;
use Tests\TestCase;
class ExampleTest extends TestCase
{
/**
* 一个基本的测试示例。
*/
public function test_基本测试(): void
{
$response = $this->get('/');
$response->dumpHeaders();
$response->dumpSession();
$response->dump();
}
}
或者,您可以使用dd
、ddHeaders
和ddSession
方法来转储有关响应的信息,然后停止执行:
<?php
test('基本测试', function () {
$response = $this->get('/');
$response->ddHeaders();
$response->ddSession();
$response->dd();
});
<?php
namespace Tests\Feature;
use Tests\TestCase;
class ExampleTest extends TestCase
{
/**
* 一个基本的测试示例。
*/
public function test_基本测试(): void
{
$response = $this->get('/');
$response->ddHeaders();
$response->ddSession();
$response->dd();
}
}
异常处理
有时您可能需要测试您的应用程序是否抛出特定的异常。要实现这一点,您可以通过Exceptions
外观“伪造”异常处理程序。一旦异常处理程序被伪造,您可以使用assertReported
和assertNotReported
方法对请求期间抛出的异常进行断言:
<?php
use App\Exceptions\InvalidOrderException;
use Illuminate\Support\Facades\Exceptions;
test('异常被抛出', function () {
Exceptions::fake();
$response = $this->get('/order/1');
// 断言抛出了异常...
Exceptions::assertReported(InvalidOrderException::class);
// 对异常进行断言...
Exceptions::assertReported(function (InvalidOrderException $e) {
return $e->getMessage() === '订单无效。';
});
});
<?php
namespace Tests\Feature;
use App\Exceptions\InvalidOrderException;
use Illuminate\Support\Facades\Exceptions;
use Tests\TestCase;
class ExampleTest extends TestCase
{
/**
* 一个基本的测试示例。
*/
public function test_异常被抛出(): void
{
Exceptions::fake();
$response = $this->get('/');
// 断言抛出了异常...
Exceptions::assertReported(InvalidOrderException::class);
// 对异常进行断言...
Exceptions::assertReported(function (InvalidOrderException $e) {
return $e->getMessage() === '订单无效。';
});
}
}
assertNotReported
和assertNothingReported
方法可用于断言在请求期间未抛出给定的异常或未抛出任何异常:
Exceptions::assertNotReported(InvalidOrderException::class);
Exceptions::assertNothingReported();
您可以通过在发出请求之前调用withoutExceptionHandling
方法来完全禁用给定请求的异常处理:
$response = $this->withoutExceptionHandling()->get('/');
此外,如果您想确保您的应用程序没有使用被 PHP 语言或您的应用程序正在使用的库弃用的功能,您可以在发出请求之前调用withoutDeprecationHandling
方法。当弃用处理被禁用时,弃用警告将被转换为异常,从而导致您的测试失败:
$response = $this->withoutDeprecationHandling()->get('/');
assertThrows
方法可用于断言给定闭包中的代码抛出指定类型的异常:
$this->assertThrows(
fn () => (new ProcessOrder)->execute(),
OrderInvalid::class
);
如果您想检查并对抛出的异常进行断言,您可以将一个闭包作为assertThrows
方法的第二个参数提供:
$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
test('发出 API 请求', function () {
$response = $this->postJson('/api/user', ['name' => 'Sally']);
$response
->assertStatus(201)
->assertJson([
'created' => true,
]);
});
<?php
namespace Tests\Feature;
use Tests\TestCase;
class ExampleTest extends TestCase
{
/**
* 一个基本的功能测试示例。
*/
public function test_发出_API_请求(): void
{
$response = $this->postJson('/api/user', ['name' => 'Sally']);
$response
->assertStatus(201)
->assertJson([
'created' => true,
]);
}
}
此外,JSON 响应数据可以作为响应上的数组变量进行访问,这使得您可以方便地检查 JSON 响应中返回的各个值:
expect($response['created'])->toBeTrue();
$this->assertTrue($response['created']);
[!注意]
assertJson
方法将响应转换为数组,以验证应用程序返回的 JSON 响应中存在给定的数组。因此,如果 JSON 响应中还有其他属性,只要给定的片段存在,此测试仍将通过。
断言精确的 JSON 匹配
如前所述,assertJson
方法可用于断言 JSON 响应中存在一段 JSON。如果您想验证给定的数组精确匹配您的应用程序返回的 JSON,您应该使用assertExactJson
方法:
<?php
test('断言精确的 JSON 匹配', function () {
$response = $this->postJson('/user', ['name' => 'Sally']);
$response
->assertStatus(201)
->assertExactJson([
'created' => true,
]);
});
<?php
namespace Tests\Feature;
use Tests\TestCase;
class ExampleTest extends TestCase
{
/**
* 一个基本的功能测试示例。
*/
public function test_断言精确的_JSON_匹配(): void
{
$response = $this->postJson('/user', ['name' => 'Sally']);
$response
->assertStatus(201)
->assertExactJson([
'created' => true,
]);
}
}
对 JSON 路径进行断言
如果您想验证 JSON 响应在指定路径包含给定的数据,您应该使用assertJsonPath
方法:
<?php
test('断言 JSON 路径值', function () {
$response = $this->postJson('/user', ['name' => 'Sally']);
$response
->assertStatus(201)
->assertJsonPath('team.owner.name', 'Darian');
});
<?php
namespace Tests\Feature;
use Tests\TestCase;
class ExampleTest extends TestCase
{
/**
* 一个基本的功能测试示例。
*/
public function test_断言_JSON_路径值(): 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);
流畅的 JSON 测试
Laravel 还提供了一种漂亮的方式来流畅地测试您的应用程序的 JSON 响应。首先,将一个闭包传递给assertJson
方法。这个闭包将被调用,并传入一个Illuminate\Testing\Fluent\AssertableJson
实例,您可以使用它对应用程序返回的 JSON 进行断言。where
方法可用于对 JSON 的特定属性进行断言,而missing
方法可用于断言 JSON 中缺少特定的属性:
use Illuminate\Testing\Fluent\AssertableJson;
test('流畅的 JSON', function () {
$response = $this->getJson('/users/1');
$response
->assertJson(fn (AssertableJson $json) =>
$json->where('id', 1)
->where('name', 'Victoria Faith')
->where('email
#### 理解 `etc` 方法
在上述示例中,您可能已经注意到我们在断言链的末尾调用了 `etc` 方法。此方法告知 Laravel,JSON 对象上可能存在其他属性。如果未使用 `etc` 方法,并且 JSON 对象上存在您未进行断言的其他属性,则测试将失败。
这种行为的目的是通过强制您要么对属性明确进行断言,要么通过 `etc` 方法明确允许其他属性,从而保护您不会在 JSON 响应中无意地暴露敏感信息。
但是,您应该注意,在断言链中不包含 `etc` 方法并不能确保不会向嵌套在 JSON 对象中的数组添加其他属性。`etc` 方法仅确保在调用 `etc` 方法的嵌套级别上不存在其他属性。
#### 断言属性的存在/不存在
要断言属性是否存在,您可以使用 `has` 和 `missing` 方法:
```php
$response->assertJson(fn (AssertableJson $json) =>
$json->has('data')
->missing('message')
);
此外,hasAll
和 missingAll
方法允许同时断言多个属性的存在或不存在:
$response->assertJson(fn (AssertableJson $json) =>
$json->hasAll(['status', 'data'])
->missingAll(['message', 'code'])
);
您可以使用 hasAny
方法来确定给定属性列表中是否至少有一个属性存在:
$response->assertJson(fn (AssertableJson $json) =>
$json->has('status')
->hasAny('data', 'message', 'code')
);
针对 JSON 集合进行断言
通常,您的路由会返回一个包含多个项目的 JSON 响应,例如多个用户:
Route::get('/users', function () {
return User::all();
});
在这些情况下,我们可以使用流畅的 JSON 对象的 has
方法对响应中包含的用户进行断言。例如,让我们断言 JSON 响应包含三个用户。接下来,我们将使用 first
方法对集合中的第一个用户进行一些断言。first
方法接受一个闭包,该闭包接收另一个可断言的 JSON 字符串,我们可以使用它对 JSON 集合中的第一个对象进行断言:
$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 集合:
Route::get('/users', function () {
return [
'meta' => [...],
'users' => User::all(),
];
})
在测试这些路由时,您可以使用 has
方法对集合中的项目数量进行断言。此外,您可以使用 has
方法来限定断言链的范围:
$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()
)
);
但是,您可以不必对 users
集合进行两次单独的 has
方法调用,而是可以进行一次调用,并将一个闭包作为其第三个参数。这样,闭包将自动被调用并限定到集合中的第一个项目:
$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
方法来实现这一点:
$response->assertJson(fn (AssertableJson $json) =>
$json->whereType('id', 'integer')
->whereAllType([
'users.0.name' =>'string',
'meta' => 'array'
])
);
您可以使用 |
字符指定多种类型,或者将类型数组作为第二个参数传递给 whereType
方法。如果响应值是列出的任何类型之一,则断言将成功:
$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
门面的 fake
方法,极大地简化了文件上传的测试。例如,您可以结合这两个功能轻松测试头像上传表单:
<?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
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
门面提供的 assertMissing
方法:
Storage::fake('avatars');
//...
Storage::disk('avatars')->assertMissing('missing.jpg');
假文件自定义
当使用 UploadedFile
类提供的 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 还允许您在不向应用程序发出模拟 HTTP 请求的情况下渲染视图。要实现此目的,您可以在测试中调用 view
方法。view
方法接受视图名称和一个可选的数据数组。该方法返回一个 Illuminate\Testing\TestView
实例,该实例提供了几个方法,可方便地对视图的内容进行断言:
<?php
test('a welcome view can be rendered', function () {
$view = $this->view('welcome', ['name' => 'Taylor']);
$view->assertSee('Taylor');
});
<?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
实例强制转换为字符串来获取原始的、渲染后的视图内容:
$contents = (string) $this->view('welcome');
共享错误
某些视图可能依赖于 Laravel 提供的全局错误包 中共享的错误。要使用错误消息填充错误包,您可以使用 withViewErrors
方法:
$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
实例:
$view = $this->blade(
'<x-component :name="$name" />',
['name' => 'Taylor']
);
$view->assertSee('Taylor');
您可以使用 component
方法来评估和渲染 Blade 组件。component
方法返回一个 Illuminate\Testing\TestComponent
实例:
$view = $this->component(Profile::class, ['name' => 'Taylor']);
$view->assertSee('Taylor');
可用的断言
响应断言
Laravel 的 Illuminate\Testing\TestResponse
类提供了多种自定义断言方法,您可以在测试应用程序时使用。这些断言可以在 json
、get
、post
、put
和 delete
测试方法返回的响应上访问:
assertAccepted assertBadRequest assertConflict assertCookie assertCookieExpired assertCookieNotExpired assertCookieMissing assertCreated assertDontSee assertDontSeeText assertDownload assertExactJson assertExactJsonStructure assertForbidden assertFound assertGone assertHeader assertHeaderMissing assertInternalServerError assertJson assertJsonCount assertJsonFragment assertJsonIsArray assertJsonIsObject assertJson Missing assertJson MissingExact assertJson MissingValidationErrors assertJsonPath assertJson MissingPath assertJsonStructure assertJsonValidationErrors assertJsonValidationErrorFor assertLocation assertMethodNotAllowed assertMovedPermanently assertContent assertNoContent assertStreamedContent assertNotFound assertOk assertPaymentRequired assertPlainCookie assertRedirect assertRedirectContains assertRedirectToRoute assertRedirectToSignedRoute assertRequestTimeout assertSee assertSeeInOrder assertSeeText assertSeeTextInOrder assertServerError assertServiceUnavailable assertSessionHas assertSessionHasInput assertSessionHasAll assertSessionHasErrors assertSessionHasErrorsIn assertSessionHasNoErrors assertSessionDoesntHaveErrors assertSession Missing assertStatus assertSuccessful assertTooManyRequests assertUnauthorized assertUnprocessable assertUnsupportedMediaType assertValid assertInvalid assertViewHas assertViewHasAll assertViewIs assertView Missing
assertBadRequest
断言响应具有错误请求(400)HTTP 状态码:
$response->assertBadRequest();
assertAccepted
断言响应具有已接受(202)HTTP 状态码:
$response->assertAccepted();
assertConflict
断言响应具有冲突(409)HTTP 状态码:
$response->assertConflict();
assertCookie
断言响应包含给定的 cookie:
$response->assertCookie($cookieName, $value = null);
assertCookieExpired
断言响应包含给定的已过期的 cookie:
$response->assertCookieExpired($cookieName);
assertCookieNotExpired
断言响应包含给定的未过期的 cookie:
$response->assertCookieNotExpired($cookieName);
assertCookieMissing
断言响应不包含给定的 cookie:
$response->assertCookieMissing($cookieName);
assertCreated
断言响应具有 201 HTTP 状态码:
$response->assertCreated();
assertDontSee
断言应用程序返回的响应中不包含给定的字符串。除非您将第二个参数设置为 false
,否则此断言将自动转义给定的字符串:
$response->assertDontSee($value, $escaped = true);
assertDontSeeText
断言响应文本中不包含给定的字符串。除非您将第二个参数设置为 false
,否则此断言将自动转义给定的字符串。此方法将在进行断言之前将响应内容传递给 strip_tags
PHP 函数:
$response->assertDontSeeText($value, $escaped = true);
assertDownload
断言响应是一个“下载”。通常,这意味着
assertJson
断言响应包含给定的 JSON 数据:
$response->assertJson(array $data, $strict = false);
assertJson
方法将响应转换为数组,以验证应用程序返回的 JSON 响应中存在给定的数组。因此,如果 JSON 响应中存在其他属性,只要给定的片段存在,此测试仍将通过。
assertJsonCount
断言响应 JSON 在给定键处具有预期数量的项的数组:
$response->assertJsonCount($count, $key = null);
assertJsonFragment
断言响应在响应的任何位置包含给定的 JSON 数据:
Route::get('/users', function () {
return [
'users' => [
[
'name' => 'Taylor Otwell',
],
],
];
});
$response->assertJsonFragment(['name' => 'Taylor Otwell']);
assertJsonIsArray
断言响应 JSON 是一个数组:
$response->assertJsonIsArray();
assertJsonIsObject
断言响应 JSON 是一个对象:
$response->assertJsonIsObject();
assertJsonMissing
断言响应不包含给定的 JSON 数据:
$response->assertJsonMissing(array $data);
assertJson MissingExact
断言响应不包含确切的 JSON 数据:
$response->assertJson MissingExact(array $data);
assertJson MissingValidationErrors
断言响应对于给定的键没有 JSON 验证错误:
$response->assertJson MissingValidationErrors($keys);
[!NOTE]
更通用的 assertValid 方法可用于断言响应中没有作为 JSON 返回的验证错误并且没有错误闪存在会话存储中。
assertJsonPath
断言响应在指定路径处包含给定的数据:
$response->assertJsonPath($path, $expectedValue);
例如,如果您的应用程序返回以下 JSON 响应:
{
"user": {
"name": "Steve Schoger"
}
}
您可以这样断言 user
对象的 name
属性与给定值匹配:
$response->assertJsonPath('user.name', 'Steve Schoger');
assertJson MissingPath
断言响应不包含给定的路径:
$response->assertJson MissingPath($path);
例如,如果您的应用程序返回以下 JSON 响应:
{
"user": {
"name": "Steve Schoger"
}
}
您可以断言它不包含 user
对象的 email
属性:
$response->assertJson MissingPath('user.email');
assertJsonStructure
断言响应具有给定的 JSON 结构:
$response->assertJsonStructure(array $structure);
例如,如果您的应用程序返回的 JSON 响应包含以下数据:
{
"user": {
"name": "Steve Schoger"
}
}
您可以这样断言 JSON 结构符合您的期望:
$response->assertJsonStructure([
'user' => [
'name',
]
]);
有时,您的应用程序返回的 JSON 响应可能包含对象数组:
{
"user": [
{
"name": "Steve Schoger",
"age": 55,
"location": "Earth"
},
{
"name": "Mary Schoger",
"age": 60,
"location": "Earth"
}
]
}
在这种情况下,您可以使用 *
字符来断言数组中所有对象的结构:
$response->assertJsonStructure([
'user' => [
'*' => [
'name',
'age',
'location'
]
]
]);
assertJsonValidationErrors
断言响应对于给定的键具有给定的 JSON 验证错误。当针对验证错误作为 JSON 结构返回而不是闪存在会话中的响应进行断言时,应使用此方法:
$response->assertJsonValidationErrors(array $data, $responseKey = 'errors');
[!NOTE]
更通用的 assertInvalid 方法可用于断言响应具有作为 JSON 返回的验证错误或错误闪存在会话存储中。
assertJsonValidationErrorFor
断言响应对于给定的键有任何 JSON 验证错误:
$response->assertJsonValidationErrorFor(string $key, $responseKey = 'errors');
assertMethodNotAllowed
断言响应具有方法不允许(405)HTTP 状态码:
$response->assertMethodNotAllowed();
assertMovedPermanently
断言响应具有永久移动(301)HTTP 状态码:
$response->assertMovedPermanently();
assertLocation
断言响应在 Location
标头中具有给定的 URI 值:
$response->assertLocation($uri);
assertContent
断言给定的字符串与响应内容匹配:
$response->assertContent($value);
assertNoContent
断言响应具有给定的 HTTP 状态码且没有内容:
$response->assertNoContent($status = 204);
assertStreamedContent
断言给定的字符串与流式响应内容匹配:
$response->assertStreamedContent($value);
assertNotFound
断言响应具有未找到(404)HTTP 状态码:
$response->assertNotFound();
assertOk
断言响应具有 200 HTTP 状态码:
$response->assertOk();
assertPaymentRequired
断言响应具有付款要求(402)HTTP 状态码:
$response->assertPaymentRequired();
assertPlainCookie
断言响应包含给定的未加密 Cookie:
$response->assertPlainCookie($cookieName, $value = null);
assertRedirect
断言响应是重定向到给定的 URI:
$response->assertRedirect($uri = null);
assertRedirectContains
断言响应是否重定向到包含给定字符串的 URI:
$response->assertRedirectContains($string);
assertRedirectToRoute
断言响应是重定向到给定的命名路由:
$response->assertRedirectToRoute($name, $parameters = []);
assertRedirectToSignedRoute
断言响应是重定向到给定的签名路由:
$response->assertRedirectToSignedRoute($name = null, $parameters = []);
assertRequestTimeout
断言响应具有请求超时(408)HTTP 状态码:
$response->assertRequestTimeout();
assertSee
断言给定的字符串包含在响应中。除非您将第二个参数传递为 false
,否则此断言将自动转义给定的字符串:
$response->assertSee($value, $escaped = true);
assertSeeInOrder
断言给定的字符串按顺序包含在响应中。除非您将第二个参数传递为 false
,否则此断言将自动转义给定的字符串:
$response->assertSeeInOrder(array $values, $escaped = true);
assertSeeText
断言给定的字符串包含在响应文本中。除非您将第二个参数传递为 false
,否则此断言将自动转义给定的字符串。在进行断言之前,响应内容将传递给 strip_tags
PHP 函数:
$response->assertSeeText($value, $escaped = true);
assertSeeTextInOrder
断言给定的字符串按顺序包含在响应文本中。除非您将第二个参数传递为 false
,否则此断言将自动转义给定的字符串。在进行断言之前,响应内容将传递给 strip_tags
PHP 函数:
$response->assertSeeTextInOrder(array $values, $escaped = true);
assertServerError
断言响应具有服务器错误(>= 500 , < 600)HTTP 状态码:
$response->assertServerError();
assertServiceUnavailable
断言响应具有“服务不可用”(503)HTTP 状态码:
$response->assertServiceUnavailable();
assertSessionHas
断言会话包含给定的数据:
$response->assertSessionHas($key, $value = null);
如果需要,可以将闭包作为 assertSessionHas
方法的第二个参数提供。如果闭包返回 true
,则断言将通过:
$response->assertSessionHas($key, function (User $value) {
return $value->name === 'Taylor Otwell';
});
assertSessionHasInput
断言会话在闪存输入数组中具有给定的值:
$response->assertSessionHasInput($key, $value = null);
如果需要,可以将闭包作为 assertSessionHasInput
方法的第二个参数提供。如果闭包返回 true
,则断言将通过:
use Illuminate\Support\Facades\Crypt;
$response->assertSessionHasInput($key, function (string $value) {
return Crypt::decryptString($value) === 'secret';
});
assertSessionHasAll
断言会话包含给定的键/值对数组:
$response->assertSessionHasAll(array $data);
例如,如果您的应用程序的会话包含 name
和 status
键,您可以这样断言两者都存在并具有指定的值:
$response->assertSessionHasAll([
'name' => 'Taylor Otwell',
'status' => 'active',
]);
assertSessionHasErrors
断言会话对于给定的 $keys
包含错误。如果 $keys
是关联数组,则断言会话对于每个字段(键)包含特定的错误消息(值)。当测试将验证错误闪存在会话中而不是作为 JSON 结构返回的路由时,应使用此方法:
$response->assertSessionHasErrors(
array $keys = [], $format = null, $errorBag = 'default'
);
例如,要断言 name
和 email
字段的验证错误消息已闪存在会话中,您可以这样调用 assertSessionHasErrors
方法:
$response->assertSessionHasErrors(['name', 'email']);
或者,您可以断言给定字段具有特定的验证错误消息:
$response->assertSessionHasErrors([
'name' => 'The given name was invalid.'
]);
[!NOTE]
更通用的 assertInvalid 方法可用于断言响应具有作为 JSON 返回的验证错误或错误闪存在会话存储中。
assertSessionHasErrorsIn
断言会话在特定的错误包中对于给定的 $keys
包含错误。如果 $keys
是关联数组,则断言会话在错误包中对于每个字段(键)包含特定的错误消息(值):
$response->assertSessionHasErrorsIn($errorBag, $keys = [], $format = null);
assertSessionHasNoErrors
断言会话没有验证错误:
$response->assertSessionHasNoErrors();
assertSessionDoesntHaveErrors
断言会话对于给定的键没有验证错误:
$response->assertSessionDoesntHaveErrors($keys = [], $format = null, $errorBag = 'default');
[!NOTE]
更通用的 assertValid 方法可用于断言响应中没有作为 JSON 返回的验证错误并且没有错误闪存在会话存储中。
assertSession Missing
断言会话不包含给定的键:
$response->assertSession Missing($key);
assertStatus
断言响应具有给定的 HTTP 状态码:
$response->assertStatus($code);
assertSuccessful
断言响应具有成功的(>= 200 且 < 300)HTTP 状态码:
$response->assertSuccessful();
assertTooManyRequests
断言响应具有过多请求(429)HTTP 状态码:
$response->assertTooManyRequests();
assertUnauthorized
断言响应具有未经授权(401)HTTP 状态码:
$response->assertUnauthorized();
assertUnprocessable
断言响应具有无法处理的实体(422)HTTP 状态码:
$response->assertUnprocessable();
assertUnsupportedMediaType
断言响应具有不支持的媒体类型(415)HTTP 状态码:
$response->assertUnsupportedMediaType();
assertValid
断言响应对于给定的键没有验证错误。此方法可用于针对验证错误作为 JSON 结构返回或验证错误已闪存在会话中的响应进行断言:
// 断言不存在验证错误...
$response->assertValid();
// 断言给定的键没有验证错误...
$response->assertValid(['name', 'email']);
assertInvalid
断言响应对于给定的键具有验证错误。此方法可用于针对验证错误作为 JSON 结构返回或验证错误已闪存在会话中的响应进行断言:
$response->assertInvalid(['name', 'email']);
您还可以断言给定的键具有特定的验证错误消息。在这样做时,您可以提供整个消息或仅消息的一小部分:
$response->assertInvalid([
'name' => 'The name field is required.',
'email' => 'valid email address',
]);
assertViewHas
断言响应视图包含给定的数据:
$response->assertViewHas($key, $value = null);
将闭包作为 assertViewHas
方法的第二个参数传递将允许您检查并对特定的视图数据进行断言:
$response->assertViewHas('user', function (User $user) {
return $user->name === 'Taylor';
});
此外,视图数据可以作为响应上的数组变量进行访问,以便您方便地进行检查:
expect($response['name'])->toBe('Taylor');
$this->assertEquals('Taylor', $response['name']);
assertViewHasAll
断言响应视图具有给定的数据列表:
$response->assertViewHasAll(array $data);
此方法可用于断言视图仅包含与给定键匹配的数据:
$response->assertViewHasAll([
'name',
'email',
]);
或者,您可以断言视图数据存在且具有特定值:
$response->assertViewHasAll([
'name' => 'Taylor Otwell',
'email' => 'taylor@example.com,',
]);
assertViewIs
断言给定的视图是由路由返回的:
$response->assertViewIs($value);
assertView Missing
断言给定的数据键未提供给应用程序响应中返回的视图:
$response->assertView Missing($key);
认证断言
Laravel 还提供了各种与认证相关的断言,您可以在应用程序的功能测试中使用。请注意,这些方法是在测试类本身而不是由 get
和 post
等方法返回的 Illuminate\Testing\TestResponse
实例上调用的。
assertAuthenticated
断言用户已通过认证:
$this->assertAuthenticated($guard = null);
assertGuest
断言用户未通过认证:
$this->assertGuest($guard = null);
assertAuthenticatedAs
断言特定用户已通过认证:
$this->assertAuthenticatedAs($user, $guard = null);
验证断言
Laravel 提供了两个主要的与验证相关的断言,您可以用来确保您的请求中提供的数据是有效的或无效的。
assertValid
断言响应对于给定的键没有验证错误。此方法可用于针对验证错误作为 JSON 结构返回或验证错误已闪存在会话中的响应进行断言:
// 断言不存在验证错误...
$response->assertValid();
// 断言给定的键没有验证错误...
$response->assertValid(['name', 'email']);
assertInvalid
断言响应对于给定的键具有验证错误。此方法可用于针对验证错误作为 JSON 结构返回或验证错误已闪存在会话中的响应进行断言:
$response->assertInvalid(['name', 'email']);
您还可以断言给定的键具有特定的验证错误消息。在这样做时,您可以提供整个消息或仅消息的一小部分:
$response->assertInvalid([
'name' => 'The name field is required.',
'email' => 'valid email address',
]);