nmtysh.log

Tech系のネタや日々の独り言などを書いています。

CakePHP の $useDbConfig にはまった(備忘録)

結論: FixtureのuseDbConfigでDataSourceを指定するには、対になるDataSourceが定義されてないと駄目でした。
例) $test_hoge = array(/* ... */); なら $hoge = array(/* ... */); が定義されてないと駄目。


動的にDBの接続先を切り替えるプログラムを書いていて、Unitテストも別々のテスト用のDBにアクセスさせようとしていたのですが、かなり嵌ってしまいました。

$useDbConfig プロパティを指定することで、テストモデルの データベースをオーバーライドできます。テーブルが正しいデータベースで 生成されるように、関連するフィクスチャが同じ値を使うことを確認してください。
テスト - CakePHP Cookbook v2.x documentation

とあったので、Fixtureでテスト用に用意した別のDBに接続させたいため、FixtureにuseDbConfigで設定してました。

例えば、

public $default = array(/* ... */);

// 動的にプログラムの中で接続先DB名を変更
public $hogehoge = array(/* ... */);

// 上の開発用デフォルトDB
public $default_hoge = array(/* ... */);

// $default のテスト用DB
public $test = array(/* ... */);

// 開発用DBのテスト用DB
public $test_hoge = array(/* ... */);

なDataSourceがあって、Modelには

class TableA extends AppModel {

    public $useDbConfig = "default";
}

class TableB extends AppModel {

    public $useDbConfig = "hogehoge";

    function __construct($id = false, $table = null, $ds = null ) {
        parent::__construct($id, $table, $ds);
        $db = ConnectionManager::getDataSource("hogehoge");
        $db->config['database'] = 'fuga';
        $db->reconnect();
    }
}

Fixtureには

class TableAFixture extends CakeTestFixture {

    public $useDbConfig = "test";
}

class TableBFixture extends CakeTestFixture {

    public $useDbConfig = "test_hoge";
}

と書きました。
ですが、いざテストを実行してみるとTableBを利用するテストもDataSourceは"test"を向いてしまい、
Table table_b for model TableB was not found in datasource test.
とエラーになってしまったのです。
debugレベル2で出るクエリログではtest_hogeにデータを入れてテーブルを作成しているのですが、肝心のテスト内でtest_hogeを向いてくれませんでした。

色々探しているとリファレンスに気になる記述がありました。

$useDbConfig プロパティはフィクスチャが使うデータソースの定義をします。 複数のデータソースを使うときは、モデルのデータソースと合わせてフィクスチャを 作るようにします。ただし、 test_ というプレフィックスをつけてください。 たとえば、 mydb というデータソースを使うモデルの場合は、フィクスチャの データソースを test_mydb とします。もし test_mydb の接続が 存在しなかったときは規定値として mydb がデータソースとして使われます。 テストを実行するときにテーブル名の衝突を避けるため、フィクスチャのデータソースには test の接頭辞が必ず付きます。
テスト - CakePHP Cookbook v2.x documentation

そこで試しに"default_hoge"を"hoge"に変えてみると、TableBのFixtureでちゃんと"test_hoge"を使ってくれるようになりました。

public $default = array(/* ... */);

// 動的にプログラムの中で接続先DB名を変更
public $hogehoge = array(/* ... */);

// 上の開発用デフォルトDB
public $hoge = array(/* ... */);

// $default のテスト用DB
public $test = array(/* ... */);

// 開発用DBのテスト用DB
public $test_hoge = array(/* ... */);
class TableAFixture extends CakeTestFixture {

    public $useDbConfig = "test";
}

class TableBFixture extends CakeTestFixture {

    public $useDbConfig = "test_hoge";
}

どうやら対になるDataSourceが無いと駄目なようです。
test_から始まるDataSource名で有ればよいのだと勘違いをしていました。

とほほ。自分の勘違いとはいえ解決にかなり時間を使ってしまいました。


参考:
テスト - CakePHP Cookbook v2.x documentation