(PHPUnit 5 未満では)データプロバイダでモックオブジェクトを作成しないほうがいい

前提

PHPUnit 5 未満を使用している(問題の確認をしたのは PHPUnit 4.8.21)。

問題

指定したメソッドが一回だけコールされることを確かめるテストで、指定したメソッドが一回も呼ばれていないのにテストが成功してしまう。

モックオブジェクトはデータプロバイダで生成している。

具体的には

以下のコード(some.php)がある。このテストを実行すると失敗するはず。。。

なのだが、PHPUnit を実行すると成功してしまう。

$ ./phpunit-4.8.21.phar some.php
PHPUnit 4.8.21 by Sebastian Bergmann and contributors.

.

Time: 141 ms, Memory: 12.00Mb

OK (1 test, 0 assertions)

解決

  • モックオブジェクトをデータプロバイダではなくテストメソッド内で生成するようにする。

or

  • テストケース内で $mock->__phpunit_verify() を呼ぶ。

前者のほうがお行儀がよさそう。

参考

この修正でデータプロバイダで生成したモックオブジェクトでもテストが期待通り実行されるようになった(issue はデータプロバイダではなく、依存関係の上流のテストケースで生成したモックオブジェクトだけれども)。

PHPUnit 5.1.3 では期待通りの結果。

./phpunit-5.1.3.phar some.php
PHPUnit 5.1.3 by Sebastian Bergmann and contributors.

F                                                                   1 / 1 (100%)

Time: 111 ms, Memory: 10.25Mb

There was 1 failure:

1) SomeTest::testStubWithProvider with data set #0 (Mock_SomeClass_0cfc834a Object (...))
Expectation failed for method name is equal to <string:doSomething> when invoked 1 time(s).
Method was expected to be called 1 times, actually called 0 times.

FAILURES!
Tests: 1, Assertions: 1, Failures: 1.