【PHPUnit】privateプロパティの値をテスト用に書き換えてテストする


そもそもprivateなもののテストを行うこと自体賛否両論あるらしいですけど、
テストは書いておいた方がいいような気がします。(小並感)
そういう場合は標準クラスのReflectionClassを使用する方法があるらしいです。

自分がよく遭遇するパターンとしては、privateプロパティをテスト用の値に書き換えたいとき。
例として以下に記します。

例)
プロパティに設定してあるファイル名が正しい場合は TRUE 、誤ってる場合は FALSE を返すメソッドのテストを行う場合

  • Registerクラス
Register.php
<?php
class Register
{
    /**
    * 登録するファイル名
    * @see  __construct()
    */
    private $registerFile;

    public function __construct()
    {
        $this->registerFile = 'AAA.csv';
    }

    public function check()
    {
        if ($this->registerFile === 'AAA.csv') {
            return true;
        }

        return false;
    }

/** 略 **/

}

以下のような感じでprivateプロパティを上書きしてやればテストが可能みたいです。(PHPUnit)

  • RegisterTestクラス
RegisterTest.php
<?php

use App\Register;

class RegisterTest extends TestCase
{
    public function test_ファイル名が適切でない場合はFALSEが返ること()
    {
        // テスト対象のクラスをインスタンス化
        $register = new Register();

        // Reflectionクラスをインスタンス化
        $reflectionClass = new ReflectionClass($register);

        // プロパティの値を取得
        $property = $reflectionClass->getProperty('registerFile');

        // privateプロパティのアクセス範囲を設定(trueを指定でアクセスできるようになる)
        $property->setAccessible(true);

        // 取得したプロパティをテスト用に上書き
        $property->setValue($register, 'AAA_test.csv');

        // 上書きしたプロパティでテストを実行
        $this->assertFalse($register->check());
    }

}

参考