CakePHP 3 のコントローラにある private や protected な関数をテストする方法
はじめに
CakePHP 3 には PHPUnit でテストするための機能が整っています。
bake コマンドを使ってコントローラなどを生成すれば、自動的にテスト用のファイルも生成されます。
CakePHP 3 の公式ドキュメントの下記ページでは、コントローラのテスト方法について説明されています。
しかし、アクション以外の private、protected メソッドのテスト方法については書かれていません。
今日は CakePHP 3 のコントローラ内にある private や protected な関数のテストを行う方法をご紹介します。
- CakePHP
- 3.8.5
- PHPUnit
- 6.5.14
- コントローラの統合テスト (CakePHP 3 Cookbook)
- https://book.cakephp.org/3.0/ja/development/testing.html#integration-testing
テスト実装方法
例として、下記コントローラの checkAnswer 関数のテストを行う場合を想定します。
この関数は引数の $answer が 試験 だったら true、異なれば false を返します。
/src/Controller/SampleController.php
<?php
namespace App\Controller;
use App\Controller\AppController;
class SampleController extends AppController
{
private function checkAnswer($answer)
{
return ($answer === '試験');
}
}
この checkAnswer() をテストするには下記のように実装します。
/tests/TestCase/Controller/SampleControllerTest.php
<?php
namespace App\Test\TestCase\Controller;
use App\Controller\SampleController;
use Cake\TestSuite\IntegrationTestTrait;
use Cake\TestSuite\TestCase;
use ReflectionClass; // ←これが必要
class SampleControllerTest extends TestCase
{
use IntegrationTestTrait;
public function testCheckAnswer()
{
$sampleCtrl = new SampleController();
$ref = new ReflectionClass($sampleCtrl);
$checkAns = $ref->getMethod('checkAnswer');
$checkAns->setAccessible(true);
$result = $checkAns->invoke($sampleCtrl, '試験');
$this->assertTrue($result);
}
}
private や protected なメソッドを呼び出すためには、ReflectionClassを利用することができます。
下から4行目にある invoke() の第二引数が、checkAnswer()への引数になります。テストしたい関数の引数が2個以上ある場合は、下記のように続けて書けばOKです。
// checkAnswer($ans1, $ans2, $ans3) のような場合
$result = $checkAns->invoke($sampleCtrl, '試験', 'しけん', 'シケン');
- PHP: ReflectionClass - Manual
- https://www.php.net/manual/ja/class.reflectionclass.php
- PHP: ReflectionClass::getMethod - Manual
- https://www.php.net/manual/ja/reflectionclass.getmethod.php
- PHP: ReflectionMethod::invoke - Manual
- https://www.php.net/manual/ja/reflectionmethod.invoke.php