もがき系プログラマの日常

もがき系エンジニアの勉強したこと、日常のこと、気になっている技術、備忘録などを紹介するブログです。

cakephp3のbootstrapでTableとるとテストが落ちちゃう

はじめに

こんばんは。

ちょっとしたハマりがありましたので、備忘録で残しておきます。

本題

cakephpでは config/bootstrap.php がかなり最初の方に呼ばれます。

それはテストでも実コードでも一緒です。

そのbootstrap上で、 $users = TableRegistry::getTableLocator()->get('Users'); みたいな感じで、テーブルをロードして、それを使おうとしている場合、コントローラのテストが落ち始めます。

例えば以下のような感じで、

<?php

$aUsers = TableRegistry::getTableLocator()->get('AUsers');
$bUsers = TableRegistry::getTableLocator()->get('BUsers');
$cUsers = TableRegistry::getTableLocator()->get('CUsers');

return [
  'Repository' => [
      'A' => new AUserRepository($aUsers),
      'B' => new BUserRepository($bUsers),
      'C' => new CUserRepository($cUsers),
  ]
];

みたいなかんじでコントローラ側でそれを使う場合に発生します。

原因

基本DBのコネクションは defaultを使うと思います。 そして、テスト時のコネクションは testを使うと思います。

cakephpのテストでは、phpunitが実行する startTest() でfixtureを読み込んでいます。 その際に、実装コードからDBに接続する場合で、テストコードからの実行の場合のみ、defaultのconnection設定をtestのものに変更するような処理が存在します。

github.com

この _aliasConnections() が実行されるより、bootstrap.phpの実行のほうがはやいので、上記のような設定を bootstrapに書くと、そこで書いている、 AUsers, BUsers ,CUsers は testコネクションに切り替える前にdefaultコネクションでインスタンス化されてしまいます。

このせいで、特定のテーブルのみ defaultコネクションをみていて、DBの取得うまくできず落ちちゃうという感じになりました。

終わりに

なかなかやらないことですが、ガッツリハマって、調べたので残しときます。

あんまり特殊なことしないほうが良いですね。

現場からは以上です。