跳至内容

HTTP 测试

简介

Laravel 提供了一个非常流畅的 API,用于向你的应用程序发出 HTTP 请求并检查响应。例如,看看下面定义的功能测试

<?php
 
test('the application returns a successful response', function () {
$response = $this->get('/');
 
$response->assertStatus(200);
});
<?php
 
namespace Tests\Feature;
 
use Tests\TestCase;
 
class ExampleTest extends TestCase
{
/**
* A basic test example.
*/
public function test_the_application_returns_a_successful_response(): void
{
$response = $this->get('/');
 
$response->assertStatus(200);
}
}

get 方法向应用程序发出 GET 请求,而 assertStatus 方法断言返回的响应应该具有给定的 HTTP 状态代码。除了这个简单的断言之外,Laravel 还包含各种断言,用于检查响应头、内容、JSON 结构等等。

发出请求

要向你的应用程序发出请求,你可以在测试中调用 getpostputpatchdelete 方法。这些方法实际上并没有向你的应用程序发出“真实”的 HTTP 请求。相反,整个网络请求是在内部模拟的。

测试请求方法不会返回 Illuminate\Http\Response 实例,而是返回 Illuminate\Testing\TestResponse 实例,它提供了一个 各种有用的断言,允许你检查应用程序的响应

<?php
 
test('basic request', function () {
$response = $this->get('/');
 
$response->assertStatus(200);
});
<?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);
}
}

通常,每个测试都应该只向你的应用程序发出一个请求。如果在一个测试方法中执行多个请求,可能会出现意外行为。

lightbulb

为了方便起见,在运行测试时会自动禁用 CSRF 中间件。

自定义请求头

你可以在请求发送到应用程序之前,使用 withHeaders 方法自定义请求的头信息。此方法允许你向请求添加任何你想要的自定义头信息

<?php
 
test('interacting with headers', 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
{
/**
* 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);
}
}

Cookie

你可以使用 withCookiewithCookies 方法在发出请求之前设置 Cookie 值。withCookie 方法接受 Cookie 名称和值作为其两个参数,而 withCookies 方法接受一个名称/值对数组

<?php
 
test('interacting with cookies', 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_interacting_with_cookies(): void
{
$response = $this->withCookie('color', 'blue')->get('/');
 
$response = $this->withCookies([
'color' => 'blue',
'name' => 'Taylor',
])->get('/');
 
//
}
}

会话/身份验证

Laravel 提供了几个在 HTTP 测试期间与会话交互的辅助函数。首先,你可以使用 withSession 方法将会话数据设置为给定的数组。这在向你的应用程序发出请求之前,用数据加载会话时很有用

<?php
 
test('interacting with the session', function () {
$response = $this->withSession(['banned' => false])->get('/');
 
//
});
<?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
 
use App\Models\User;
 
test('an action that requires authentication', 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_an_action_that_requires_authentication(): void
{
$user = User::factory()->create();
 
$response = $this->actingAs($user)
->withSession(['banned' => false])
->get('/');
 
//
}
}

你还可以通过将守卫名称作为第二个参数传递给 actingAs 方法来指定应该使用哪个守卫来认证给定的用户。提供给 actingAs 方法的守卫也将成为测试期间的默认守卫

$this->actingAs($user, 'web')

调试响应

在向你的应用程序发出测试请求后,可以使用 dumpdumpHeadersdumpSession 方法检查和调试响应内容

<?php
 
test('basic test', function () {
$response = $this->get('/');
 
$response->dumpHeaders();
 
$response->dumpSession();
 
$response->dump();
});
<?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();
}
}

或者,你可以使用 ddddHeadersddSession 方法转储有关响应的信息,然后停止执行

<?php
 
test('basic test', function () {
$response = $this->get('/');
 
$response->ddHeaders();
 
$response->ddSession();
 
$response->dd();
});
<?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 门面“模拟”异常处理程序。一旦异常处理程序被模拟,你就可以利用 assertReportedassertNotReported 方法对请求期间抛出的异常进行断言

<?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
 
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.';
});
}
}

assertNotReportedassertNothingReported 方法可以用来断言给定的异常在请求期间没有被抛出,或者没有异常被抛出

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 及其响应的辅助函数。例如,jsongetJsonpostJsonputJsonpatchJsondeleteJsonoptionsJson 方法可以用来使用各种 HTTP 动词发出 JSON 请求。你还可以轻松地将数据和头信息传递给这些方法。首先,让我们编写一个测试,向 /api/user 发出一个 POST 请求,并断言返回了预期的 JSON 数据

<?php
 
test('making an api request', 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
{
/**
* 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 响应中返回的各个值。

expect($response['created'])->toBeTrue();
$this->assertTrue($response['created']);
lightbulb

assertJson 方法将响应转换为数组,以验证给定的数组是否存在于应用程序返回的 JSON 响应中。因此,如果 JSON 响应中还有其他属性,只要存在给定的片段,此测试仍然会通过。

断言完全匹配的 JSON

如前所述,assertJson 方法可以用来断言 JSON 片段是否存在于 JSON 响应中。如果你想验证给定的数组是否 **完全匹配** 应用程序返回的 JSON,则应该使用 assertExactJson 方法

<?php
 
test('asserting an exact json match', function () {
$response = $this->postJson('/user', ['name' => 'Sally']);
 
$response
->assertStatus(201)
->assertExactJson([
'created' => true,
]);
});
<?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
 
test('asserting a json path value', 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
{
/**
* 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);

流畅的 JSON 测试

Laravel 还提供了一种流畅的方式来测试应用程序的 JSON 响应。首先,将闭包传递给 assertJson 方法。此闭包将使用 Illuminate\Testing\Fluent\AssertableJson 的实例调用,该实例可用于对应用程序返回的 JSON 进行断言。where 方法可用于对 JSON 的特定属性进行断言,而 missing 方法可用于断言 JSON 中缺少特定属性

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('[email protected]'))
->whereNot('status', 'pending')
->missing('password')
->etc()
);
});
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('[email protected]'))
->whereNot('status', 'pending')
->missing('password')
->etc()
);
}

了解 etc 方法

在上面的示例中,你可能已经注意到我们在断言链的末尾调用了 etc 方法。此方法通知 Laravel JSON 对象上可能存在其他属性。如果不使用 etc 方法,如果 JSON 对象上存在你没有对其进行断言的其他属性,则测试将失败。

此行为的目的是保护你不小心在 JSON 响应中暴露敏感信息,方法是强制你显式地对属性进行断言,或者通过 etc 方法显式地允许其他属性。

但是,你应该注意,在断言链中不包含 etc 方法并不能确保不会向嵌套在 JSON 对象中的数组添加其他属性。etc 方法仅确保在调用 etc 方法的嵌套级别不存在其他属性。

断言属性存在/不存在

要断言某个属性存在或不存在,可以使用hasmissing方法。

$response->assertJson(fn (AssertableJson $json) =>
$json->has('data')
->missing('message')
);

此外,hasAllmissingAll方法允许同时断言多个属性的存在或不存在。

$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('[email protected]'))
->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('[email protected]'))
->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('[email protected]'))
->missing('password')
->etc()
)
);

断言 JSON 类型

您可能只想断言 JSON 响应中的属性是否为某种类型。Illuminate\Testing\Fluent\AssertableJson类提供了whereTypewhereAllType方法来实现这一点。

$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'])
);

whereTypewhereAllType方法识别以下类型:stringintegerdoublebooleanarraynull

测试文件上传

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类提供以下断言方法:assertSeeassertSeeInOrderassertSeeTextassertSeeTextInOrderassertDontSeeassertDontSeeText

如果需要,可以通过将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类提供各种自定义断言方法,您可以在测试应用程序时使用这些方法。这些断言可以在jsongetpostputdelete测试方法返回的响应上访问。

assertBadRequest

断言响应具有错误请求 (400) HTTP 状态代码。

$response->assertBadRequest();

assertAccepted

断言响应具有已接受 (202) HTTP 状态代码。

$response->assertAccepted();

assertConflict

断言响应具有冲突 (409) HTTP 状态代码。

$response->assertConflict();

断言响应包含给定的 Cookie。

$response->assertCookie($cookieName, $value = null);

断言响应包含给定的 Cookie,并且它已过期。

$response->assertCookieExpired($cookieName);

断言响应包含给定的 Cookie,并且它未过期。

$response->assertCookieNotExpired($cookieName);

断言响应不包含给定的 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

断言响应是“下载”。通常,这意味着调用返回响应的路由返回了Response::download响应、BinaryFileResponseStorage::download响应。

$response->assertDownload();

如果需要,可以断言可下载文件被分配了给定的文件名。

$response->assertDownload('image.jpg');

assertExactJson

断言响应包含给定 JSON 数据的完全匹配。

$response->assertExactJson(array $data);

assertExactJsonStructure

断言响应包含给定 JSON 结构的完全匹配。

$response->assertExactJsonStructure(array $data);

此方法是assertJsonStructure的更严格的变体。与assertJsonStructure相比,如果响应包含任何未明确包含在预期 JSON 结构中的键,此方法将失败。

assertForbidden

断言响应具有禁止 (403) HTTP 状态代码。

$response->assertForbidden();

assertFound

断言响应具有已找到 (302) HTTP 状态代码。

$response->assertFound();

assertGone

断言响应具有已消失 (410) HTTP 状态代码。

$response->assertGone();

assertHeader

断言给定的标头和值存在于响应中。

$response->assertHeader($headerName, $value = null);

assertHeaderMissing

断言给定的标头不存在于响应中。

$response->assertHeaderMissing($headerName);

assertInternalServerError

断言响应具有“内部服务器错误” (500) HTTP 状态代码。

$response->assertInternalServerError();

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);

assertJsonMissingExact

断言响应不包含完全相同的 JSON 数据。

$response->assertJsonMissingExact(array $data);

assertJsonMissingValidationErrors

断言响应对于给定键没有 JSON 验证错误。

$response->assertJsonMissingValidationErrors($keys);
lightbulb

更通用的assertValid方法可用于断言响应没有作为 JSON 返回的验证错误并且没有错误闪存到会话存储中。

assertJsonPath

断言响应在指定路径处包含给定数据。

$response->assertJsonPath($path, $expectedValue);

例如,如果您的应用程序返回以下 JSON 响应

{
"user": {
"name": "Steve Schoger"
}
}

您可以断言user对象的name属性与给定值匹配,如下所示

$response->assertJsonPath('user.name', 'Steve Schoger');

assertJsonMissingPath

断言响应不包含给定的路径。

$response->assertJsonMissingPath($path);

例如,如果您的应用程序返回以下 JSON 响应

{
"user": {
"name": "Steve Schoger"
}
}

您可以断言它不包含user对象的email属性。

$response->assertJsonMissingPath('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');
lightbulb

更通用的 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();

断言响应包含给定的未加密 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);

例如,如果您的应用程序会话包含 namestatus 键,您可以断言两者都存在并具有指定的如下值。

$response->assertSessionHasAll([
'name' => 'Taylor Otwell',
'status' => 'active',
]);

assertSessionHasErrors

断言会话包含给定 $keys 的错误。如果 $keys 是一个关联数组,则断言会话对于每个字段 (键) 包含一个特定的错误消息 (值)。当测试将验证错误闪存到会话而不是将其作为 JSON 结构返回的路由时,应使用此方法。

$response->assertSessionHasErrors(
array $keys = [], $format = null, $errorBag = 'default'
);

例如,要断言 nameemail 字段具有已闪存到会话的验证错误消息,您可以像这样调用 assertSessionHasErrors 方法。

$response->assertSessionHasErrors(['name', 'email']);

或者,您可以断言给定字段具有特定的验证错误消息。

$response->assertSessionHasErrors([
'name' => 'The given name was invalid.'
]);
lightbulb

更通用的 assertInvalid 方法可用于断言响应是否具有作为 JSON 返回的验证错误 **或** 错误是否已闪存到会话存储中。

assertSessionHasErrorsIn

断言会话在特定 错误包 中包含给定 $keys 的错误。如果 $keys 是一个关联数组,则断言会话在错误包中对于每个字段 (键) 包含一个特定的错误消息 (值)。

$response->assertSessionHasErrorsIn($errorBag, $keys = [], $format = null);

assertSessionHasNoErrors

断言会话没有验证错误。

$response->assertSessionHasNoErrors();

assertSessionDoesntHaveErrors

断言会话对于给定的键没有验证错误。

$response->assertSessionDoesntHaveErrors($keys = [], $format = null, $errorBag = 'default');
lightbulb

更通用的assertValid方法可用于断言响应没有作为 JSON 返回的验证错误并且没有错误闪存到会话存储中。

assertSessionMissing

断言会话不包含给定的键。

$response->assertSessionMissing($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 结构返回或验证错误已闪存到会话中。

// Assert that no validation errors are present...
$response->assertValid();
 
// Assert that the given keys do not have validation errors...
$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' => '[email protected],',
]);

assertViewIs

断言给定的视图是由路由返回的。

$response->assertViewIs($value);

assertViewMissing

断言给定的数据键未提供给应用程序响应中返回的视图。

$response->assertViewMissing($key);

身份验证断言

Laravel 还提供各种与身份验证相关的断言,您可以在应用程序的功能测试中使用它们。请注意,这些方法是在测试类本身上调用的,而不是在 Illuminate\Testing\TestResponse 实例上调用的,该实例由 getpost 等方法返回。

assertAuthenticated

断言用户已通过身份验证。

$this->assertAuthenticated($guard = null);

assertGuest

断言用户未通过身份验证。

$this->assertGuest($guard = null);

assertAuthenticatedAs

断言特定用户已通过身份验证。

$this->assertAuthenticatedAs($user, $guard = null);

验证断言

Laravel 提供了两个主要的与验证相关的断言,您可以使用它们来确保请求中提供的数据有效或无效。

assertValid

断言响应对于给定的键没有验证错误。此方法可用于断言针对响应,其中验证错误作为 JSON 结构返回或验证错误已闪存到会话中。

// Assert that no validation errors are present...
$response->assertValid();
 
// Assert that the given keys do not have validation errors...
$response->assertValid(['name', 'email']);

assertInvalid

断言响应对于给定的键有验证错误。此方法可用于断言针对响应,其中验证错误作为 JSON 结构返回或验证错误已闪存到会话中。

$response->assertInvalid(['name', 'email']);

您还可以断言给定键具有特定的验证错误消息。这样做时,您可以提供整个消息或仅提供消息的一小部分。

$response->assertInvalid([
'name' => 'The name field is required.',
'email' => 'valid email address',
]);