PHPUnitで単体テストを書いてみる〜privateメソッド編
2024.03.15 09:00
2024.03.15 10:29

前回に引き続きPHPUnitでの単体テストについてです。
前回はpublicメソッドのテストだったのですが、今回はprivateメソッドです。
privateメソッドの場合はそのままではうまくいかなかったので、今回はprivateメソッドをテストする方法を調べてみました。
1. テストを書く
まずはテスト対象クラスです。
常にtrueを返すという、説明以外では使いようがないシンプル過ぎるクラスです。
// Hoge.php
<?php
class Hoge {
private function _hoge(): bool
{
return true;
}
}
これのテストはこんな感じ。
// HogeTest.php
<?php
use PHPUnit\Framework\TestCase;
// テストしたいクラスをインポート
require_once './Hoge.php';
class HogeTest extends TestCase
{
// ---------------------------------------------------------------------
// 準備
// ---------------------------------------------------------------------
// インスタンス用の変数
private $testClass;
// privateメソッドを読み込むためのReflectionクラス用の変数
private $reflection;
public function setUp() :void{
// 必ず親クラスのsetUpを呼んでおくこと
parent::setUp();
// テスト対象のクラスインスタンスを作成
$this->testClass = new Validation();
// privateメソッドを読み込むためにReflectionクラスを使う
$this->reflection = new ReflectionClass($this->testClass);
}
// ---------------------------------------------------------------------
// メソッドテスト
// ---------------------------------------------------------------------
public function test_check_true()
{
// Reflectionクラスを使ってprivateメソッドを読み込む
$method = $this->reflection->getMethod('_hoge');
// invokeメソッドを使って、privateメソッドを実行する
$result = $method->invoke($this->testClass);
// 検証
$this->assertTrue($result);
}
}
前段でやることが増えましたが、知ってしまえば簡単でしたね。
2. 引数があるprivateメソッドをテストする
では次は引数があるprivateメソッドのテストを書いてみます。
引数によって真偽を返すシンプルなつくりです。
// Hoge.php
<?php
class Hoge {
private function _hoge(string $value): bool
{
if($value !== '') {
return true;
} else {
return false;
}
}
}
テストはこんな感じになります。
// HogeTest.php
<?php
use PHPUnit\Framework\TestCase;
// テストしたいクラスをインポート
require_once './Hoge.php';
class HogeTest extends TestCase
{
// ---------------------------------------------------------------------
// 準備
// ---------------------------------------------------------------------
// インスタンス用の変数
private $testClass;
// privateメソッドを読み込むためのReflectionクラス用の変数
private $reflection;
public function setUp() :void{
// 必ず親クラスのsetUpを呼んでおくこと
parent::setUp();
// テスト対象のクラスインスタンスを作成
$this->testClass = new Validation();
// privateメソッドを読み込むためにReflectionクラスを使う
$this->reflection = new ReflectionClass($this->testClass);
}
// ---------------------------------------------------------------------
// メソッドテスト
// ---------------------------------------------------------------------
public function test_check_true()
{
// Reflectionクラスを使ってprivateメソッドを読み込む
$method = $this->reflection->getMethod('_hoge');
// invokeメソッドを使って、引数が1つのprivateメソッドを実行する
$result = $method->invoke($this->testClass, true);
// 検証
$this->assertTrue($result);
}
public function test_check_false()
{
// Reflectionクラスを使ってprivateメソッドを読み込む
$method = $this->reflection->getMethod('_hoge');
// invokeメソッドを使って、引数が1つのprivateメソッドを実行する
$result = $method->invoke($this->testClass, false);
// 検証
$this->assertFalse($result);
}
}
invokeのclassを指定している部分の第二引数以降に値を指定すると、テストメソッドへの引数になります。こんな感じですね。
$result = $method->invoke($this->testClass, 引数1);
引数が複数ある場合でも簡単です。
$result = $method->invoke($this->testClass, 引数1, 引数2, 引数3);
こちらも知ってしまえばなんてことはないですが、
まさかpublicとprivateでこんなに違うとは、、という感じですね。
今回は以上です!