Skip to content

Latest commit

 

History

History
1979 lines (1427 loc) · 50.4 KB

http-tests.md

File metadata and controls

1979 lines (1427 loc) · 50.4 KB

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

一般來說,每個測試應該只對您的應用程式進行一次請求。如果在單個測試方法中執行多個請求,可能會發生意外行為。

Note

為了方便起見,在執行測試時,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);
    }
}

Cookies

您可以使用 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();
    }
}

或者,您可以使用 ddddHeadersddSessionddJson 方法來將有關回應的信息輸出並停止執行:

<?php

test('basic test', function () {
    $response = $this->get('/');

    $response->ddHeaders();
    $response->ddSession();
    $response->ddJson();
    $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']);

Note

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 物件上存在您未對其進行斷言的其他屬性,測試將失敗。

這種行為背後的意圖是為了保護您免於通過強制您明確對屬性進行斷言或通過 etc 方法明確允許其他屬性,而意外地在 JSON 回應中洩露敏感信息。

但是,您應該知道,在斷言鏈中不包含 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()
            )
    );

但是,您可以不必兩次分別調用 has 方法來對 users 集合進行斷言,而是可以進行單次調用,並將閉包作為其第三個參數。這樣做時,閉包將自動被調用並範圍到集合中的第一個項目:

$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 測試方法返回的回應上進行存取:

<style> .collection-method-list > p { columns: 14.4em 2; -moz-columns: 14.4em 2; -webkit-columns: 14.4em 2; } .collection-method-list a { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } </style>

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 assertStreamed 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

斷言回應具有 "Internal Server Error"(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);

Note

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

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

assertStreamed

斷言響應是一個流式響應:

$response->assertStreamed();

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

例如,如果您的應用程序會話包含 namestatus 鍵,您可以斷言這兩者都存在並具有指定的值,如下所示:

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

assertSessionHasErrors

斷言會話包含給定 $keys 的錯誤。如果 $keys 是一個關聯陣列,則斷言會話為每個字段(key)包含特定的錯誤訊息(value)。當測試路由時,會話會將驗證錯誤快閃到會話中,而不是將它們作為 JSON 結構返回時,應使用此方法:

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

例如,要斷言nameemail字段是否有驗證錯誤訊息快閃到會話中,您可以這樣調用assertSessionHasErrors方法:

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

或者,您可以斷言特定字段是否有特定的驗證錯誤訊息:

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

Note

更通用的 assertInvalid 方法可用於斷言回應是否具有作為 JSON 返回的驗證錯誤 是否將錯誤快閃到會話存儲中。

assertSessionHasErrorsIn

斷言會話在特定 錯誤包 中包含給定 $keys 的錯誤。如果 $keys 是一個關聯陣列,則斷言會話在錯誤包中為每個字段(key)包含特定的錯誤訊息(value):

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

assertSessionHasNoErrors

斷言會話沒有驗證錯誤:

$response->assertSessionHasNoErrors();

assertSessionDoesntHaveErrors

斷言會話對於給定的鍵沒有驗證錯誤:

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

Note

更通用的 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',
]);

如果您想要斷言給定的欄位是唯一具有驗證錯誤的欄位,您可以使用 assertOnlyInvalid 方法:

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

斷言視圖具有

斷言回應視圖包含特定資料片段:

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

斷言視圖具有全部

斷言回應視圖具有給定的資料清單:

$response->assertViewHasAll(array $data);

此方法可用於斷言視圖僅包含與給定鍵匹配的資料:

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

或者,您可以斷言視圖資料存在並具有特定值:

$response->assertViewHasAll([
    'name' => 'Taylor Otwell',
    'email' => '[email protected],',
]);

斷言視圖為

斷言路由返回了給定的視圖:

$response->assertViewIs($value);

斷言視圖缺失

斷言給定的資料鍵未提供給應用程式回應中返回的視圖:

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