📖

[CakePHP4.3]見に覚えのないSQLの1062 Duplicate entryのエラー

2021/12/29に公開

前提条件

  • CakePHP4.3

  • Tableは2つUsersActivities

  • 実行していたテストは

    • UsersTableTest
    • ActivitiesControllerTest
  • composer testを実行しphpunitのテストを走らせると下記のエラーが出力。

1) App\Test\TestCase\Model\Table\UsersTableTest::testValidationDefault
PDOException: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '1' for key 'PRIMARY'
  • このApp\Test\TestCase\Model\Table\UsersTableTest::testValidationDefaultを単体で実行するとテストは通る

  • ActivitiesControllerTestを削除するとcomposer testによるテストは通る

  • ActivitiesControllerではActivitiesテーブルだけでなくUsersテーブルにデータの保存処理をしていた。

  • ActivitiesControllerTestではActivitiesFixtureの読み込みのみ行っていた。

ActiviitesControllerTest.php
protected $fixtures = [
        'app.Activities',
    ];

原因

ActivitiesControllerで実行したUsersテーブルの保存データがUsersTableTestで実行する際に削除されていませんでした。

解決策

ActivitiesControllerTestでUsersのフィクスチャを読み込む。

ActiviitesControllerTest.php
protected $fixtures = [
        'app.Activities',
        'app.Users', //追記
    ];

CakePHP4.3からフィクスチャのスキーマとデータ管理の責務が分割されました。
そのため、フィクスチャの読み込みがない場合は以前と違い初期データがないだけで問題なくテストは動きます。ただ、フィクスチャが読み込めていないとテストメソッド終了時にtruncateが実行されず、テーブルにデータが残ったままになってしまったようです。

フィクスチャを読み込まずにテーブルのデータを都合よく消してくれるメソッドはなさそうでした。なので自分で$this->Users->delete($entity);のようなコードを書いてデータを消すかフィクスチャの読み込みを行うかになりそうです。

https://book.cakephp.org/4/ja/appendices/fixture-upgrade.html

Discussion