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 结构等等。
发出请求
要向你的应用程序发出请求,你可以在测试中调用 get
、post
、put
、patch
或 delete
方法。这些方法实际上并没有向你的应用程序发出“真实”的 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); }}
通常,每个测试都应该只向你的应用程序发出一个请求。如果在一个测试方法中执行多个请求,可能会出现意外行为。
为了方便起见,在运行测试时会自动禁用 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
你可以使用 withCookie
或 withCookies
方法在发出请求之前设置 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')
调试响应
在向你的应用程序发出测试请求后,可以使用 dump
、dumpHeaders
和 dumpSession
方法检查和调试响应内容
<?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(); }}
或者,你可以使用 dd
、ddHeaders
和 ddSession
方法转储有关响应的信息,然后停止执行
<?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
门面“模拟”异常处理程序。一旦异常处理程序被模拟,你就可以利用 assertReported
和 assertNotReported
方法对请求期间抛出的异常进行断言
<?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.'; }); }}
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('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']);
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') ->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') ->whereNot('status', 'pending') ->missing('password') ->etc() );}
了解 etc
方法
在上面的示例中,你可能已经注意到我们在断言链的末尾调用了 etc
方法。此方法通知 Laravel JSON 对象上可能存在其他属性。如果不使用 etc
方法,如果 JSON 对象上存在你没有对其进行断言的其他属性,则测试将失败。
此行为的目的是保护你不小心在 JSON 响应中暴露敏感信息,方法是强制你显式地对属性进行断言,或者通过 etc
方法显式地允许其他属性。
但是,你应该注意,在断言链中不包含 etc
方法并不能确保不会向嵌套在 JSON 对象中的数组添加其他属性。etc
方法仅确保在调用 etc
方法的嵌套级别不存在其他属性。
断言属性存在/不存在
要断言某个属性存在或不存在,可以使用has
和missing
方法。
$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') ->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') ->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') ->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 assertJsonMissing assertJsonMissingExact assertJsonMissingValidationErrors assertJsonPath assertJsonMissingPath 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 assertSessionMissing assertStatus assertSuccessful assertTooManyRequests assertUnauthorized assertUnprocessable assertUnsupportedMediaType assertValid assertInvalid assertViewHas assertViewHasAll assertViewIs assertViewMissing
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
断言响应是“下载”。通常,这意味着调用返回响应的路由返回了Response::download
响应、BinaryFileResponse
或Storage::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);
更通用的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');
更通用的 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.']);
更通用的 assertInvalid 方法可用于断言响应是否具有作为 JSON 返回的验证错误 **或** 错误是否已闪存到会话存储中。
assertSessionHasErrorsIn
断言会话在特定 错误包 中包含给定 $keys
的错误。如果 $keys
是一个关联数组,则断言会话在错误包中对于每个字段 (键) 包含一个特定的错误消息 (值)。
$response->assertSessionHasErrorsIn($errorBag, $keys = [], $format = null);
assertSessionHasNoErrors
断言会话没有验证错误。
$response->assertSessionHasNoErrors();
assertSessionDoesntHaveErrors
断言会话对于给定的键没有验证错误。
$response->assertSessionDoesntHaveErrors($keys = [], $format = null, $errorBag = 'default');
更通用的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',]);
assertViewIs
断言给定的视图是由路由返回的。
$response->assertViewIs($value);
assertViewMissing
断言给定的数据键未提供给应用程序响应中返回的视图。
$response->assertViewMissing($key);
身份验证断言
Laravel 还提供各种与身份验证相关的断言,您可以在应用程序的功能测试中使用它们。请注意,这些方法是在测试类本身上调用的,而不是在 Illuminate\Testing\TestResponse
实例上调用的,该实例由 get
和 post
等方法返回。
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',]);