実現したいこと
Laravelのfactoryを使ったテストコードを記述したら、エラーが生じた。
テストコードが通るようにしたい。
前提
Laravelのfactoryを使って、テストをコード書いた際に下記のエラーが生じた。
・setUp内の変数は別のテストコードで使用している。
・testJobAssertStatusWithNoImageJobOffer内で使うComInfoモデルのデータを定義したい。
発生している問題・エラーメッセージ
1) Tests\Feature\Http\Controllers\Main\JobListControllerTest::testJobAssertStatusWithNoImageDentalStyleJobOffer Illuminate\Database\QueryException: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '0' for key 'PRIMARY' (SQL: insert into `city_infos` (`prefecture_id`, `city_cd`, `prefecture_name`, `city_name`, `prefecture_name_rome`, `city_name_rome`, `updated_at`, `created_at`) values (7, 230, Larrymouth, West Easterland, totam, eum, 2022-01-24 19:06:23, 2023-02-03 18:04:00))
該当のソースコード
テストコード
PHP
1<?php 2 3namespace Tests\Feature\Http\Controllers\Main; 4use App\CityInfo; 5use App\ComInfo; 6use App\ComJob; 7use Illuminate\Foundation\Testing\DatabaseTransactions; 8use Tests\TestCase; 9use Illuminate\Database\Eloquent\Factories\HasFactory; 10 11/** 12 * @runTestsInSeparateProcesses 13 * @preserveGlobalState disabled 14 */ 15class JobListControllerTest extends TestCase 16{ 17 use DatabaseTransactions; 18 use HasFactory; 19 20 private $job; 21 22 public function setUp(): void 23 { 24 parent::setUp(); 25 26 $this->job = ComJob::factory() 27 ->valid() 28 ->create([ 29 'comid' => ComInfo::factory() 30 ->valid() 31 ->create([ 32 'city_cd' => CityInfo::factory() 33 ]), 34 'state' => 1, 35 ]); 36 } 37 38 /** 39 * @group http 40 * @group JoblList@job 41 */ 42 public function testJobAssertStatusWithNoImageJobOffer() 43 { 44 $job_no_image = ComJob::factory() 45 ->valid() 46 ->create([ 47 'comid' => ComInfo::factory() 48 ->valid() 49 ->create([ 50 'city_cd' => CityInfo::factory(), 51 'photourl' => '', 52 'device_photo_1' => null, 53 'device_photo_2' => null, 54 'device_photo_3' => null, 55 'device_photo_4' => null, 56 'device_photo_5' => null, 57 'device_photo_6' => null, 58 'device_photo_7' => null, 59 'device_photo_8' => null, 60 'device_photo_9' => null, 61 'device_photo_10' => null, 62 'device_photo_11' => null, 63 'device_photo_12' => null, 64 'device_photo_13' => null, 65 'device_photo_14' => null, 66 ]), 67 'state' => 1, 68 ]); 69 $response = $this->get('/joblist/' . $job_no_image->id); 70 $response->assertStatus(200); 71 } 72}
モデル
PHP
1<?php 2 3namespace App; 4 5use Illuminate\Database\Eloquent\Model; 6use Illuminate\Support\Facades\DB; 7 8/** 9 * 市区町村一覧 10 */ 11class CityInfo extends Model 12{ 13 protected $fillable = [ 14 'id', // 都道府県id+市区町村id 15 'prefecture_id', // 都道府県id 16 'prefecture', // 都道府県 17 'city_id', // 市区町村id 18 'prefecture_name', // 都道府県名 19 'city_name', // 市区町村名 20 'prefecture_name_rome', // 都道府県名ローマ字 21 'city_name_rome', // 市区町村名ローマ字 22 'updated_at', // 更新日時 23 ]; 24 25 public static function getCitylist() 26 { 27 $city_list = DB::table('city_infos') 28 ->select( 29 'city_name', 30 'id', 31 'prefecture_id', 32 'city_name', 33 'city_name_rome' 34 ) 35 ->orderBy('city_infos.id', 'asc'); 36 37 return $city_list; 38 } 39 40 public static function getCityname() 41 { 42 $city_name = DB::table('city_infos') 43 ->select('city_name') 44 ->orderBy('city_infos.id', 'asc'); 45 46 return $city_name; 47 } 48 49 public static function getPagetitleCityNames($url_parameter_city_names) 50 { 51 $pagetitle_city_names = ''; 52 $city_names = explode('_', $url_parameter_city_names); 53 $city_names = DB::table('city_infos') 54 ->select('city_name') 55 ->whereIn('city_name_rome', $city_names) 56 ->get()->values()->all(); 57 foreach ($city_names as $city_name) { 58 $pagetitle_city_names .= '/' .$city_name->city_name; 59 } 60 return $pagetitle_city_names; 61 } 62 63 public static function getIdAndCityNameAndCityNameRomeWhereByPrefectureId(int $id) 64 { 65 return self::select( 66 'id', 67 'city_name', 68 'city_name_rome' 69 ) 70 ->where('prefecture_id', $id) 71 ->get(); 72 } 73 74 public static function getIdWherePrefectureIdAndWhereCityNameRomeLikeFirst(int $prefecture_id, string $city_name) 75 { 76 return self::select('id') 77 ->where('prefecture_id', $prefecture_id) 78 ->where('city_name_rome', 'like', $city_name . '%') 79 ->first(); 80 } 81 82 public static function getIdWherePrefectureId(int $id) 83 { 84 return self::select('id') 85 ->where('prefecture_id', $id) 86 ->get(); 87 } 88 89 /** 90 * @param int $prefecture_id 91 * 92 * @return object 93 */ 94 public static function wherePrefectureId(int $prefecture_id) 95 { 96 return self::where('prefecture_id', $prefecture_id) 97 ->get(); 98 } 99} 100
マイグレーションファイル
PHP
1<?php 2 3use Illuminate\Database\Migrations\Migration; 4use Illuminate\Database\Schema\Blueprint; 5 6class CreateCityInfosTable extends Migration 7{ 8 /** 9 * Run the migrations. 10 * 11 * @return void 12 */ 13 public function up() 14 { 15 Schema::create('city_infos', function (Blueprint $table) { 16 $table->integer('id')->unsigned()->primary(); 17 $table->boolean('prefecture_id')->index('prefecture_id_idx')->comment('都道府県ID'); 18 $table->integer('city_cd')->unsigned()->comment('市区町村コード'); 19 $table->string('prefecture_name')->comment('都道府県名'); 20 $table->string('city_name')->comment('市区町村名'); 21 $table->string('prefecture_name_rome')->comment('都道府県名 ローマ字表記'); 22 $table->string('city_name_rome')->comment('市区町村名 ローマ字表記'); 23 $table->timestamps(); 24 }); 25 } 26 27 28 /** 29 * Reverse the migrations. 30 * 31 * @return void 32 */ 33 public function down() 34 { 35 Schema::drop('city_infos'); 36 } 37}
試したこと
主キー制約の重複によって引き起こされているので、CityInfoFactoryクラスのid(主キー)にuniqueメソッドを追加。
PHP
1 2<?php 3 4namespace Database\Factories; 5 6use App\CityInfo; 7use Faker\Generator as Faker; 8use Illuminate\Database\Eloquent\Factories\Factory; 9 10class CityInfoFactory extends Factory 11{ 12 protected $model = CityInfo::class; 13 14 public function definition() 15 { 16 return [ 17 'id' => $this->faker->unique()->numberBetween(1, 10000), 18 'prefecture_id' => $this->faker->numberBetween(1, 47), 19 'city_cd' => $this->faker->numberBetween(100, 699), 20 'prefecture_name' => $this->faker->city, 21 'city_name' => $this->faker->city, 22 'prefecture_name_rome' => $this->faker->word, 23 'city_name_rome' => $this->faker->word, 24 'updated_at' => $this->faker->dateTime(), 25 ]; 26 } 27}
テストは通らずに下記のエラーが発生
[previous exception] [object] (ErrorException(code: 0): Attempt to read property \"id\" on null at /var/www/storage/framework/views/fccee8ff7ff1b2984c57e75f46f03b88bf2d6d20.php:117)
補足情報(FW/ツールのバージョンなど)
環境:PHP 8.1、Laravel8
テストフレームワーク PHPUnit
何かご助言頂けますと幸いです。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2023/02/03 10:17
2023/02/03 10:18
2023/02/03 10:27
2023/02/03 10:43 編集
2023/02/03 11:14
2023/02/03 11:18
2023/02/03 12:39