- 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メソッドのテストをする方法を解説しました。
少しでも参考になっていれば幸いです。
