Laravel 5.1 測試時模擬 user 登入

最近這幾天都在寫測試,花蠻多時間的,不熟之外,資源也不夠齊(不好找,有時 L4, L5 參雜,自己都搞混了)。

如果你是用 Laravel 4,那麼請參考 4 的說明 (有一段:『 You may set the currently authenticated user using the be method』從這邊開始 )。

在 Laravel 5.1 測試 user 登入狀態,要用 Model Factories 的方式,在這裡也要感謝小鐵大大,幫了我很多忙 :P。


大概的重點如下
* 在 phpunit 測試 code 裡面,使用 factory 去 fake 一個 $user,如官方文件說明,看你想要用 make() 還是 create()。另外我也意外地發現 $faker 蠻方便的,很開心的在 database/factories/ModelFactory.php 盡量學習用 $faker XD

我的 sample code,不是很完美,大概描述一下作法類似這樣子而已:
因為之後有很多模組或是功能都會需要這個假裝有 user 登入的測試情況,所以把它寫在外面 (TestCase去),繼承 TestCase 的測試 php 就都可以使用。
// TestCase.php

protected function demoUserLoginIn()
{
    $user = factory(App\User::class)->make();
    // Use model in tests...
    // 登入 user
    $this->be($user);
}

繼承 TestCase 的測試程式:
//  某隻 extends 自 TestCase 的測試.php

public function testLogout()
{  
    // 使用 TestCase 的 demoUserLoginIn
    $this->demoUserLoginIn();

    // 檢查登入狀態
    $this->assertTrue(Auth::check());
    // do other things...
}

* 另外一種測法是,只是測試資料帶入 form 然後登入的情況,一樣也可以模擬出登入的情況,只是每次都要繞到登入頁,這種測法就比較適合單純測登入表單的情況。

測試 form 登入,資料帶入 POST 的情況,要小心 csrf 的問題,還要在測試加上 Session::start();。
public function testLogin()
{
    Log::info('testLoginSuccess');
      Session::start();
    
    $this->call('POST', '/login', [
        'username' => 'winwuloveyou',
        'password' => '123456',
        '_token' => csrf_token(),
    ]);

    $this->assertRedirectedTo('dashboard');
}


參考
書目:「Basic TDD in Laravel 5」作者: Jace Ju.
Testing Laravel 5 Routes with CSRF Protection Using PHPUnit
https://laracasts.com/series/whats-new-in-laravel-5-1/episodes/5


留言

這個網誌中的熱門文章

[Android] 筆記 手機上測試自己的 APP

解決fatal: Not a git repository (or any of the parent directories): .git錯誤

[Android 筆記] 設定 ImageView 的圖檔來源