15分鐘搞懂 Livewire 的組件測試實作

15分鐘搞懂 Livewire 的組件測試實作

Livewire 提供了一組功能強大的工具來測試你的組件

這是一個 Livewire 組件以及相應的測試,以示範基礎知識

//app/Http/Livewire/CreatePost.php

class CreatePost extends Component
{
    public $title;

    protected $rules = [
        'title' => 'required',
    ];

    public function create()
    {
        auth()->user()->posts()->create(
            $this->validate()
        );

        return redirect()->to('/posts');
    }
}
//resources/views/livewire/create-post.blade.php

<form wire:submit.prevent="create">
    <input wire:model="title" type="text">

    <button>Create Post</button>
</form>
//tests/Unit/CreatePostTest.php

class CreatePostTest extends TestCase
{
    /** @test  */
    function can_create_post()
    {
        $this->actingAs(User::factory()->create());

        Livewire::test(CreatePost::class)
            ->set('title', 'foo')
            ->call('create');

        $this->assertTrue(Post::whereTitle('foo')->exists());
    }

    /** @test  */
    function can_set_initial_title()
    {
        $this->actingAs(User::factory()->create());

        Livewire::test(CreatePost::class, ['initialTitle' => 'foo'])
            ->assertSet('title', 'foo');
    }

    /** @test  */
    function title_is_required()
    {
        $this->actingAs(User::factory()->create());

        Livewire::test(CreatePost::class)
            ->set('title', '')
            ->call('create')
            ->assertHasErrors(['title' => 'required']);
    }

    /** @test  */
    function is_redirected_to_posts_page_after_creation()
    {
        $this->actingAs(User::factory()->create());

        Livewire::test(CreatePost::class)
            ->set('title', 'foo')
            ->call('create')
            ->assertRedirect('/posts');
    }
}

測試組件狀態

Livewire 註冊了方便的 PHPUnit 方法來測試頁面上組件的存在

//tests/Unit/CreatePostTest.php

class CreatePostTest extends TestCase
{
    /** @test  */
    function post_creation_page_contains_livewire_component()
    {
        $this->get('/posts/create')->assertSeeLivewire('create-post');
    }

    /** @test  */
    function post_creation_page_doesnt_contain_livewire_component()
    {
        $this->get('/posts/create')->assertDontSeeLivewire('edit-post');
    }
}

使用查詢字符串參數進行測試

要測試 Livewire 的 $queryString 功能,可以使用 Livewire:: withQueryParams 來測試應用

//tests/Unit/CreatePostTest.php

class CreatePostTest extends TestCase
{
    /** @test  */
    function post_creation_page_contains_livewire_component()
    {
        Livewire::withQueryParams(['foo' => 'bar'])
            ->test(ShowFoo::class)
            ->assertSet('foo', 'bar')
            ->assertSee('bar');
    }
}

所有測試方法

以下列出所有 Livewire 所提供的測試方法

Livewire::actingAs($user);
// 在測試中以所提供用戶來進行登入

Livewire::withQueryParams(['foo' => 'bar']);
// 設定查詢參數 foo 為 bar,以供 Livewire 組件的 $queryString 屬性抓取

Livewire::test('foo', ['bar' => $bar]);
// 測試 "foo" 組件,並將 "bar" 設定為參數

->set('foo', 'bar');
// 設定 "foo" 屬性(`public $foo`) 為 "bar"

->call('foo');
// 呼叫 "foo" 方法

->call('foo', 'bar', 'baz');
// Call the "foo" method, and pass the "bar" and "baz" parameters
// 呼叫 "foo" 方法,並傳入 "bar" 和 "baz" 參數

->emit('foo');
// 發送 "foo" 事件

->emit('foo', 'bar', 'baz');
// 發送 "foo" 事件,並傳入 "bar" 和 "baz" 參數

->assertSet('foo', 'bar');
// 確認 "foo" 屬性是否設定為 "bar",包含計算屬性

->assertNotSet('foo', 'bar');
// 確認 "foo" 屬性是否並未設定為 "bar",包含計算屬性

->assertPayloadSet('foo', 'bar');
// 確認 由 Livewire 所回傳透過 JavaScript 載入的 "foo" 屬性是否設定為 "bar"

->assertPayloadNotSet('foo', 'bar');
// 確認 由 Livewire 所回傳透過 JavaScript 載入的 "foo" 屬性是否並未設定為 "bar"

->assertViewIs('foo')
// 確認當前渲染的視圖為 "foo"

->assertSee('foo');
// 確認當前組件所渲染的內容是否包含 "foo" 字串

->assertDontSee('foo');
// 確認當前組件所渲染的內容是否並未包含 "foo" 字串

->assertSeeHtml('<h1>foo</h1>');
// 確認當前組件所渲染的HTML內容是否包含'<h1>foo</h1>' 字串

->assertDontSeeHtml('<h1>foo</h1>');
// 確認當前組件所渲染的HTML內容是否並未包含'<h1>foo</h1>' 字串

->assertSeeInOrder(['foo', 'bar']);
// 確認當前組件所渲染的內容中,"foo" 是否出現在 "bar" 之前

->assertSeeHtmlInOrder(['<h1>foo</h1>', '<h1>bar</h1>']);
// 確認當前組件所渲染的HTML內容中,'<h1>foo</h1>' 是否出現在 '<h1>bar</h1>' 之前

->assertEmitted('foo');
// 確認 "foo" 事件是否有發出

->assertEmitted('foo', 'bar', 'baz');
// 確認 "foo" 事件發出時,是否帶 "bar" 和 "baz" 參數

->assertNotEmitted('foo');
// 確認 "foo" 事件是否並未發出

->assertHasErrors('foo');
// 確認 "foo" 屬性是否有驗證錯誤

->assertHasErrors(['foo', 'bar']);
// 確認 "foo" 和 "bar" 屬性是否都有驗證錯誤

->assertHasErrors(['foo' => 'required']);
// 確認 "foo" 屬性是否有必填規則的驗證錯誤

->assertHasErrors(['foo' => ['required', 'min']]);
// 確認 "foo" 屬性是否有必填和最小值等規則的驗證錯誤

->assertHasNoErrors('foo');
// 確認 "foo" 屬性是否並未有驗證錯誤

->assertHasNoErrors(['foo', 'bar']);
// 確認 "foo" 和 "bar" 屬性是否並未有驗證錯誤

->assertNotFound();
// 確認組件所引發的錯誤狀態碼是否為404

->assertRedirect('/some-path');
// Assert that a redirect was triggered from the component
// 確認組件是否觸發轉址到 some-path

->assertUnauthorized();
// 確認組件所引發的錯誤狀態碼是否為401

->assertForbidden();
// 確認組件所引發的錯誤狀態碼是否為403

->assertStatus(500);
// 確認組件所引發的錯誤狀態碼是否為500

->assertDispatchedBrowserEvent('event', $data);
// 確認一個瀏覽器事件是否被組件透過->dispatchBrowserEvent(...))發送

分享這篇文章:

關聯文章:

訂閱電子報,索取 Laravel 學習手冊

價值超過 3000 元,包含常用 Laravel 語法與指令!

一小時免費求職講座

3個應徵軟體工程師前該知道的秘訣

取得免費課程連結

Laravel 百萬年薪特訓營

從最基礎的 PHP 語法開始,包含所有你該知道的網頁基礎知識,連同 Laravel 從零開始一直到實戰,最後還將告訴你如何找好工作,讓你及早擁有百萬年薪