ぷっぽプログラミング備忘録

linux, javascript, php, C#, そのうちScalaとかアプリ開発とかやってみたいです。

Laravelのunittest(overload使う場合、mockだとonce()がテストされなかった。spyを使えばOKだった)

状況

Laravelのunittestで強い依存のあるメソッドをテストしたい。 また、強い依存のあるメソッド内で、あるメソッドが一度も呼ばれないこと をテストしたい。

class Foo {
  public function bar($isCallSituation) {
      //... 中略...
      if ( $isCallSituation ) {
        $hoge = new Hoge();
        $hoge->fuga();
      }
      //... 後略...
  }
}

結果

  • mockを使った場合
$mock = Mockery::mock('overload:Hoge');
$mock->shouldNotReceive('fuga'); 
// $mock->shouldReceive('fuga')->once();  // <--- 上をコメントアウトして、当行を実行してもテストが通ってしまった…

$foo = new Foo();
$foo->bar(false);

shouldNotReceive('テストしたいメソッド')でもshouldReceive('テストしたいメソッド')->once() でも、どちらでもテスト結果が通ってしまった…。 (事実一度も呼ばれてないはずなので、shouldReceive('テストしたいメソッド')->once()の場合はエラーになってほしいのに)

  • spyを使った場合
$mock = Mockery::spy('overload:Hoge');
$mock->shouldNotHaveReceive('fuga'); 
// $mock->shouldHaveReceive('fuga');  // <--- 上をコメントアウトして、当行を実行したらエラーになった!

$foo = new Foo();
$foo->bar(false);

shouldNotHaveReceive('テストしたいメソッド')はOK、shouldHaveReceive('テストしたいメソッド')はエラーになった!

考察(正しいかどうかはわかりません!)

  • mockの場合は、一度もnewされない場合は、検証が実行されない?
  • spyの場合は、一度もnewされなくても検証が実行される?

どなたかこのあたりのことご存知の方、教えていただけると嬉しいです

参考

強い依存のモック:Mockery1.0

スパイ:Mockery1.0