LoginSignup
1

More than 3 years have passed since last update.

PHPUnitのバージョンアップで使えなくなったgetMock()の置き換え法(草刈り)

Posted at

環境

  • php 5.6.21
  • phpUnit 5.7.27
  • Xdebug 2.4.0

前置き

たまたまPHPUnit5.7.27が入っている環境の触れる機会がありました。
この環境でテストを実行すると以下のように大量の警告が出てきて「何事だ!?」となったのが始まりです。
スクリーンショット 2020-09-02 16.40.51.png
↑大量の警告が出て大草原になっています
この警告を消して(草刈りして)いきたいと思います。

警告の内容

警告の内容は以下の通りです。

PHPUnit_Framework_TestCase::getMock() is deprecated, use PHPUnit_Framework_TestCase::createMock() or PHPUnit_Framework_TestCase::getMockBuilder() instead

getMockは廃止予定だからcreateMockgetMockBuilderに置き換えてねという内容です。

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をオーバーライドする形で置き換えます。
適当な場所に以下のようなファイルを作成します。

tests/TestAdapter.php
<?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で呼び出します。

tests/init.php
require_once dirname(__FILE__) . '/TestAdapter.php';// 適当な場所に追記してください。

あとは各テストでPHPUnit_Framework_TestCaseを呼び出していた箇所をTestAdapterに変えていけばOKです!

- class hogetest extends PHPUnit_Framework_TestCase
+ class hogetest extends TestAdapter

置き換え後のテスト結果

スクリーンショット 2020-09-11 12.17.5.png

きれいになりました!

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1