- PHPでprivateメソッドやprotectedメソッドのテストって書けるの?
- PHPでprivateメソッドのテストを書く方法が分からない。。
当記事はこういった方向け。
PHPUnitでprivateメソッド(protectedメソッド)のテストをする方法をご紹介します。
PHPUnitでprivate・protectedメソッドのテストをする方法
結論から言うと、PHPUnitでprivate・protectedメソッドのテストをするには、ReflectionMethodクラスを利用します。
ReflectionMethodクラスはPHP5以上から標準搭載されているクラスで、メソッドについての情報を報告することができます。
それでは、具体例を見つつPHPUnitでprivate・protectedメソッドのテストをする方法を学んでいきましょう。
まずは簡単なprivate,protectedメソッドの実装を用意します。
引数に渡す値の合計が指定した値ならtrueを返す単純な実装です。
<?php namespace App; class sample { private function test1($a, $b) { if ($a + $b == 2) { return true; } return false; } protected function test2($a, $b) { if ($a + $b == 3) { return true; } return false; } }
さらにこの実装に対するテストコードも実装します。
<?php namespace Tests; use App\sample; use Tests\TestCase; class sampleTest extends TestCase { /** @test */ public function test1_合計値が2ならtrueを返す() { $this->assertTrue((new sample)->test1(1, 1)); } /** @test */ public function test1_合計値が2でなければfalseを返す() { $this->assertFalse((new sample)->test1(5, 1)); } /** @test */ public function test1_合計値が3ならtrueを返す() { $this->assertTrue((new sample)->test2(2, 1)); } /** @test */ public function test1_合計値が3でなければfalseを返す() { $this->assertFalse((new sample)->test2(7, 1)); } }
これでテストを回すと。。
privateメソッドやprotectedメソッドにアクセスできないので怒られます。
このような状況でprivateメソッド・protectedメソッドのテストをするには、テストコードを以下のように変更します。
<?php namespace Tests; use App\sample; use ReflectionMethod; use Tests\TestCase; class sampleTest extends TestCase { /** @test */ public function test1_合計値が2ならtrueを返す() { $method = new ReflectionMethod(sample::class, 'test1'); $method->setAccessible(true); $this->assertTrue($method->invoke(new sample, 1, 1)); } /** @test */ public function test1_合計値が2でなければfalseを返す() { $method = new ReflectionMethod(sample::class, 'test1'); $method->setAccessible(true); $this->assertFalse($method->invoke(new sample, 5, 1)); } /** @test */ public function test1_合計値が3ならtrueを返す() { $method = new ReflectionMethod(sample::class, 'test2'); $method->setAccessible(true); $this->assertTrue($method->invoke(new sample, 2, 1)); } /** @test */ public function test1_合計値が3でなければfalseを返す() { $method = new ReflectionMethod(sample::class, 'test2'); $method->setAccessible(true); $this->assertFalse($method->invoke(new sample, 7, 1)); } }
まずはnew ReflectionMethodでReflectionMethod のインスタンスを作成します。
ReflectionMethodはメソッドについての情報を報告するクラスです。
第一引数にclass名、第二引数に呼び出すテスト名を指定します。
次に、setAccessibleメソッド を呼び出します。
この引数にtrueを指定することで、先ほどReflectionMethodの引数に指定したメソッドがprivateやprotectedであってもアクセス可能になります。
最後にinvokeでメソッドを実行します。
ここでは第一引数に呼び出すクラスのインスタンスを指定し、第二引数以降にメソッドに渡す引数を指定します。
実際にテストを回してみましょう。
全てのテストが通っています。(privateメソッドやprotectedメソッドにアクセスできている)
PHPUnitでprivate・protectedメソッドのテストをする方法 おわりに
この記事ではPHPUnitでpriveteメソッドやprotectedメソッドのテストをする方法を解説しました。
少しでも参考になっていれば幸いです。