モックを使ったテストについて

http://1-byte.jp/2010/08/29/cakephp%E3%81%A7%E3%83%95%E3%82%A3%E3%82%AF%E3%82%B9%E3%83%81%E3%83%A3%E3%81%AB%E6%83%91%E3%82%8F%E3%81%95%E3%82%8C%E3%81%9A%E3%81%AB%E3%83%86%E3%82%B9%E3%83%88%E3%82%92%E6%9B%B8%E3%81%8F%E6%96%B9/ を参考にテストを作成して分かったこと、気をつけようと思ったことなど。

  • expectCallCount($method, $n) は「このメソッドを実行するテストメソッドを実行中に何回呼ばれたか」を検証する

よって、

function testLogin() {
  // ケース1
  $this->user->expectCallCount('get', 1);
  $this->user->expectAt(1, 'get', array('id'=>'0001');
  $this->user->setReturnValueAt(1, 'get', null);
  $this->assertEqual($this->api->login('0001'), false); // login() 内で user->get() しているものとする
  // 中略
  // ケース2
  $this->user->expectCallCount('get', 2);
  $this->user->expectAt(2, 'get', array('id'=>'0002');
  // 以下略
}

みたいな使い方は出来ない。
正確には、最後に書かれた expectCallCount のチェックだけが行われて、他は無視される。

  • 上記の理由により、一つのテストメソッド内で複数のケースを対象としたテストは書きにくい

expectAt(), setReturnValueAt() の第一引数に書くべき値は、テスト子どの作成者がテストメソッド内の処理を完全に把握して「自力で」カウントしないといけない。それは作業コストが高いうえに、途中にコードの追加を行った場合は修正しなければならず、テストコードをメンテするコストも高い。
基本的に 〜At は使わない(= expect(), setReturnValue()を使う)ようにし、異なるケースはメソッドを分割するようにすべき。それとももっと他のやり方があるのだろうか…?