環境
- php 5.6.21
- phpUnit 5.7.27
- Xdebug 2.4.0
前置き
たまたまPHPUnit5.7.27が入っている環境の触れる機会がありました。
この環境でテストを実行すると以下のように大量の警告が出てきて「何事だ!?」となったのが始まりです。
↑大量の警告が出て大草原になっています
この警告を消して(草刈りして)いきたいと思います。
警告の内容
警告の内容は以下の通りです。
PHPUnit_Framework_TestCase::getMock() is deprecated, use PHPUnit_Framework_TestCase::createMock() or PHPUnit_Framework_TestCase::getMockBuilder() instead
getMock
は廃止予定だからcreateMock
かgetMockBuilder
に置き換えてねという内容です。
getMock()の仕様
舞台裏では、getMock() メソッドが使われたときに PHPUnit が自動的に、求める振る舞いを実装した新たな PHP のクラスを生成しています。 生成されるテストダブルクラスの設定は、 getMock() メソッドのオプションの引数を使って行います。
デフォルトでは、指定したクラスのすべてのメソッドが単に NULL を返すだけのテストダブルとなります。返り値を変更するには、たとえば will($this->returnValue()) を使います。
オプションの第二パラメータを指定すると、その配列の中に含まれる名前のメソッドだけがテストダブルに置き換えらて、その他のメソッドはそのままとなります。パラメータに NULL を渡すと、どのメソッドも置き換えません。
オプションの第三パラメータには、元クラスのコンストラクタに渡すパラメータの配列を渡します (デフォルトでは、コンストラクタはダミー実装に置き換えられません)。
オプションの第四パラメータを使うと、生成されるテストダブルクラスのクラス名を指定することができます。
オプションの第五パラメータを使うと、元クラスのコンストラクタを呼び出さないようにすることができます。
オプションの第六パラメータを使うと、元クラスの clone コンストラクタを呼び出さないようにすることができます。
オプションの第七パラメータを使うと、テストダブルクラスの生成時に __autoload() を無効にすることができます。
https://phpunit.de/manual/3.7/ja/test-doubles.html
これを置き換えていきます!
getMockBuilderで置き換えていく!
仕様を読んで置き換えていくと以下のようになります。
getMock(hoge1,hoge2,hoge3,hoge4,hoge5,hoge6,hoge7);
// 置き換え後
getMockBuilder(hoge1)
->setMethods(hoge2) // 置き換えたいメソッドを指定
->setConstructorArgs(hoge3) // コンストラクタに渡す引数を指定
->setMockClassName(hoge4) // 生成されるテストダブルクラスのクラス名を指定
->disableOriginalConstructor(hoge5) // 元クラスのクローンコンストラクタを無効にする
->disableOriginalClone(hoge6) // 元クラスのクローンコンストラクタを無効にする
->disableAutoload(hoge7) // __autoload()を無効にする
->getMock(); // モックの取得
今回は置き換えの該当箇所がとても多いので、getMock
をオーバーライドする形で置き換えます。
適当な場所に以下のようなファイルを作成します。
<?php
class TestAdapter extends PHPUnit_Framework_TestCase
{
public function getMock($originalClassName, $methods = array(), array $arguments = array(), $mockClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true)
{
// モックの生成
$mockObject = $this->getMockBuilder($originalClassName);
// 置き換えたいメソッドを指定。
if (!empty($methods)) {
$mockObject = $mockObject->setMethods($methods);
}
// コンストラクタに渡す引数を指定
if (!empty($arguments)) {
$mockObject = $mockObject->setConstructorArgs($arguments);
}
if ($mockClassName != '') {
$mockObject = $mockObject->setMockClassName($mockClassName);
}
// 元クラスのクローンコンストラクタを無効にする
if (!$callOriginalConstructor) {
$mockObject = $mockObject->disableOriginalConstructor();
}
// 元クラスのクローンコンストラクタを無効にする
if (!$callOriginalClone) {
$mockObject = $mockObject->disableOriginalClone();
}
// __autoload()を無効にする
if (!$callAutoload) {
$mockObject = $mockObject->disableAutoload();
}
// 生成
$mockObject = $mockObject->getMock();
return $mockObject;
}
}
これをinit.php
で呼び出します。
require_once dirname(__FILE__) . '/TestAdapter.php';// 適当な場所に追記してください。
あとは各テストでPHPUnit_Framework_TestCase
を呼び出していた箇所をTestAdapter
に変えていけばOKです!
- class hogetest extends PHPUnit_Framework_TestCase
+ class hogetest extends TestAdapter
置き換え後のテスト結果
きれいになりました!