朝からPRONTOに行って、個人開発アプリTranderの開発を進めた。前回から課題になっていたSettingApiTest
の実装を進めた。内容は、/api/setting
へのPOST
リクエストが成功することを確かめるものだ。
しかし、リクエスト時にパラメータを送信しない実装であるため、ログインユーザーとしてどのようにテストするかを課題にしていた。
結論としては、ログイン(/api/login
へのPOST
リクエスト)→セッティング(/api/setting
へのPOST
リクエスト)という流れで実装できた。以下に全体の流れを示す。
- ①テストユーザ作成
- ②作成したテストユーザ検索
- ③ログイン
- ④setting_APIにリクエストして成功する
前提
- Laravel 5.7
- PHP 7.2
- PHPUnit 7.5.18
①テストユーザ作成
factory
を使ってテーブルにデータを挿入している。
$this->setting = factory(Setting::class)->states('register user and safe distance')->create();
基になるSetting::class
を用意しておいて、state
で値を差し替える形にした。テストケースに応じて柔軟にテストデータを用意できるひとつの方法だと判断したからだ。以下は作成したSettingFactory.php
である。
<?php
use Illuminate\Support\Str;
use Faker\Generator as Faker;
/**
* setting登録
*/
$factory->define(App\Setting::class, function (Faker $faker) {
return [
'user_id' => null,
'min_distance' => null,
'max_distance' => null,
];
});
/**
* setting登録(ユーザー登録・範囲内の距離)
*/
$factory->state(App\Setting::class, 'register user and safe distance', function (Faker $faker) {
return [
'user_id' => function () {
return factory(App\User::class)->create()->id;
},
'min_distance' => 15,
'max_distance' => 78,
];
});
なお、user_id
はusers
テーブルのid
と紐付ける形にしている。
②作成したテストユーザ検索
作成したテストユーザを取得している
$user = DB::table('users')->where('id', $this->setting->user_id)->first();
③ログイン
$user
を使い、/api/login
にPOST
リクエストを送信してログインする。
$response_test = $this->json('POST', route('login'), [
'email' => $user->email,
'password' => 'secret',
]);
④setting_APIにリクエストして成功する
/api/setting
にPOST
リクエストを送信し、正しくレスポンスが返ってくるか確認している。
$response = $this->post(route('setting'));
$response
->assertStatus(200)
->assertJson([
'user_id' => $this->setting->user_id,
'min_distance' => $this->setting->min_distance,
'max_distance' => $this->setting->max_distance
]);
結論
パラメータなしで、かつログインユーザとしてある機能にPOST
リクエストを送る必要がある場合、PHPUnitでのテストはまず/api/login
にPOST
リクエストを送信してログインしてから実施する必要がある。
他に良い方法、ベターな書き方があればコメント欄でお知らせください。