Q&A
前提
Docker+Laravel9(Laravel sail 8.1)+postgresQL14+Inertia0.6.3+Vue3
認証系にLaravel Breezeを使用(usersテーブルはカスタムしており、後述の通り外部キー制約を含む)
上記の設定で、WindowsにてWebアプリを開発しております。
PHP Unitテストを実行するとエラーが出てしまい、色々試しましたが解決できません。
実現したいこと
以下のエラーが出ないようにしたいです。
発生している問題・エラーメッセージ
There was 1 error: 1) Tests\Feature\Auth\AuthenticationTest::test_users_can_not_authenticate_with_invalid_password Illuminate\Database\QueryException: SQLSTATE[23503]: Foreign key violation: 7 ERROR: insert or update on table "users" violates foreign key constraint "users_message_accept_type_id_foreign" DETAIL: Key (message_accept_type_id)=(1) is not present in table "message_accept_types". (SQL: insert into **(省略)**) (省略) Caused by PDOException: SQLSTATE[23503]: Foreign key violation: 7 ERROR: insert or update on table "users" violates foreign key constraint "users_message_accept_type_id_foreign" DETAIL: Key (message_accept_type_id)=(1) is not present in table "message_accept_types". (省略)
該当のソースコード
テストファイル
php
1<?php 2 3(省略) 4 5class AuthenticationTest extends TestCase 6{ 7 use RefreshDatabase; 8 9 public function test_users_can_authenticate_using_the_login_screen() 10 { 11 Schema::disableForeignKeyConstraints(); 12 $this->seed([ 13 MessageAcceptTypesTableSeeder::class, 14 ]); 15 $user = User::factory()->create(); 16 17 $response = $this->post('/login', [ 18 'email' => $user->email, 19 'password' => 'password' 20 ]); 21 22 $this->assertAuthenticated(); 23 $response->assertRedirect(RouteServiceProvider::HOME); 24 Schema::enableForeignKeyConstraints(); 25 } 26 27 public function test_users_can_not_authenticate_with_invalid_password() 28 { 29 Schema::disableForeignKeyConstraints(); 30 $this->seed([ 31 MessageAcceptTypesTableSeeder::class, 32 ]); 33 $user = User::factory()->create(); 34 35 $this->post('/login', [ 36 'email' => $user->email, 37 'password' => 'wrong-password' 38 ]); 39 40 $this->assertGuest(); 41 Schema::enableForeignKeyConstraints(); 42 } 43 44}
usersテーブル マイグレーションファイル抜粋
php
1 public function up() 2 { 3 // ユーザー情報テーブル 4 Schema::create('users', function (Blueprint $table) { 5 $table->id(); 6 $table->string('user_name'); 7 $table->string('email')->unique()->nullable(); 8 $table->timestamp('email_verified_at')->nullable(); 9 $table->string('password')->nullable(); 10 $table->bigInteger('message_accept_type_id'); 11 $table->foreign('message_accept_type_id')->references('id')->on('message_accept_types'); 12 (一部省略。message_accept_type_idの他に外部キー制約のあるカラムはありません) 13 $table->rememberToken(); 14 $table->timestamps(); 15 }); 16 }
message_accept_typesテーブル マイグレーションファイル抜粋
php
1public function up() 2 { 3 // メッセージ送信種別テーブル(Admin管理) 4 Schema::create('message_accept_types', function (Blueprint $table) { 5 $table->id(); 6 $table->string('message_accept_type_name'); 7 $table->timestamps(); 8 }); 9 }
message_accept_typesテーブル シーダーファイル
php
1(省略) 2 3class MessageAcceptTypesTableSeeder extends Seeder 4{ 5 /** 6 * Run the database seeds. 7 * 8 * @return void 9 */ 10 public function run() 11 {DB::table('message_accept_types')->insert([ 12 [ 13 'message_accept_type_name' => json_encode([ 14 'ja' => 'テスト1' 15 ]), 16 ], 17 [ 18 'message_accept_type_name' => json_encode([ 19 'ja' => 'テスト2' 20 ]), 21 ], 22 [ 23 'message_accept_type_name' => json_encode([ 24 'ja' => 'テスト3' 25 ]), 26 ], 27 ]); 28 29 } 30}
$sail php artisan migrate:fresh --seed 実行時、マイグレーション・シーダーともにすべて成功することを確認しています。
試したこと
関数を一部削除することで、エラーが出ずテストが成功することを確認しています。
失敗するコード↓
php
1(省略) 2 3class AuthenticationTest extends TestCase 4{ 5 use RefreshDatabase; 6 7 public function test_users_can_authenticate_using_the_login_screen() 8 { 9 Schema::disableForeignKeyConstraints(); 10 $this->seed([ 11 MessageAcceptTypesTableSeeder::class, 12 ]); 13 $user = User::factory()->create(); 14 15 $response = $this->post('/login', [ 16 'email' => $user->email, 17 'password' => 'password' 18 ]); 19 20 $this->assertAuthenticated(); 21 $response->assertRedirect(RouteServiceProvider::HOME); 22 Schema::enableForeignKeyConstraints(); 23 } 24 25 public function test_users_can_not_authenticate_with_invalid_password() 26 { 27 Schema::disableForeignKeyConstraints(); 28 $this->seed([ 29 MessageAcceptTypesTableSeeder::class, 30 ]); 31 $user = User::factory()->create(); 32 33 $this->post('/login', [ 34 'email' => $user->email, 35 'password' => 'wrong-password' 36 ]); 37 38 $this->assertGuest(); 39 Schema::enableForeignKeyConstraints(); 40 } 41 42} 43
成功するコード↓
※test_users_can_not_authenticate_with_invalid_passwordを削除しただけです。
逆にtest_users_can_authenticate_using_the_login_screenを削除した場合も成功します。
php
1(省略) 2 3class AuthenticationTest extends TestCase 4{ 5 use RefreshDatabase; 6 7 public function test_users_can_authenticate_using_the_login_screen() 8 { 9 Schema::disableForeignKeyConstraints(); 10 $this->seed([ 11 MessageAcceptTypesTableSeeder::class, 12 ]); 13 $user = User::factory()->create(); 14 15 $response = $this->post('/login', [ 16 'email' => $user->email, 17 'password' => 'password' 18 ]); 19 20 $this->assertAuthenticated(); 21 $response->assertRedirect(RouteServiceProvider::HOME); 22 Schema::enableForeignKeyConstraints(); 23 } 24 25} 26
ちなみに、全く同じ内容の関数を名前だけ変えて二回繰り返させた場合、やはり二回目だけ失敗します。
単純に書き方がおかしいだけなのか、pgSQL特有のキャッシュなど?が絡んでいるのか、もう半日くらい悩んでいてどうしようもないので質問させて頂きました。
お心当たりの方がいらっしゃいましたら、お知恵をお貸しください。
何卒宜しくお願い致します。
回答1件
あなたの回答
tips
プレビュー
下記のような回答は推奨されていません。
このような回答には修正を依頼しましょう。
2022/12/03 02:44