な、なんだってー!?
PHP-CLIのSAPIだとfilter_input()を実行しても値がnullになりテストができない・・・
$_GET['key'] = 'value'
var_dump($_GET['key']);
// string(5) "value"
var_dump(filter_input(INPUT_GET, 'key'));
// null
というわけで組み込み関数でもMockを作ってテストしてみます。
この方法は他の組み込み関数でも使えるはずなので、ぜひ使ってみてください。
サンプルのコードはこんな感じ。
TargetService.php
<?php
namespace App\Service;
class TargetService
{
public function __construct(){}
/**
* URLパラメータにkeyがあり値がvalueであることを
* 確認するメソッド
* @return bool
*/
public function targetMethod()
{
return filter_input(INPUT_GET, 'key') === 'value';
}
}
TargetServiceTest.php
<?php
namespace App\Service;
require_once 'PHPUnit\Framework\TestCase.php';
class TargetServiceTest extends \PHPUnit_Framework_TestCase
{
/**
* Create test subject before test
*/
protected function setUp()
{
parent::setUp();
$this->target = new App\Service\TargetService();
}
/*
* Test cases
*/
public function testTargetMethod()
{
$this->assertTrue($this->target->targetMethod());
}
}
このような場合に上記のようにtargetMethod()をテストしようと思いPHPUnitで単体テストを作成してもPHPUnitはSAPIがPHP-CLIのためfilter_input()を実行しても値がnullになりAssertが通リません。
そうした時はこのように単体テストを書くと組み込み関数のfilter_input()をオーバーライドできます。
TargetControllerTest.php
<?php
namespace App\Service;
require_once 'PHPUnit\Framework\TestCase.php';
/**
* filter_input()をオーバーライド
*/
function filter_input()
{
return 'value';
}
class TargetServiceTest extends \PHPUnit_Framework_TestCase
{
/**
* Create test subject before test
*/
protected function setUp()
{
parent::setUp();
$this->target = new App\Service\TargetService();
}
/*
* Test cases
*/
public function testTargetMethod()
{
$this->assertTrue($this->target->targetMethod());
}
}
ポイントは必ず組み込み関数と同じ名前を関数に名付けることです!
参考文献
PHP: “Mocking” built-in functions like time() in Unit Tests