注意
2018年8月にprivate,protectedなメソッドを呼び出してテストする(新)を書いたので、そちらを参考にしてください。
どうしてもpublic
にしたくないメソッドをテストしたいなー、ってときに無理やりメソッドを呼び出す。
/**
* メソッドと同じように呼べる無名函数を返す
*/
function callMethodAsPublic($class, $method)
{
$ref = new \ReflectionMethod($class, $method);
$ref->setAccessible(true);
$obj = (gettype($class) === 'object') ? $class : null;
return function () use ($class, $ref, $obj) {
$args = func_get_args();
return $ref->invokeArgs($obj, $args);
};
}
静的メソッドでも動的メソッドでも呼べるようにした。でもバッドノウハウくさくてうーんって感じだ。うーん…
うーんって感じなので、作ったはいいものの、自分でも使ってない。
例
Testklass.php
<?php
class Testklass
{
public function publicMethod ($str)
{
return "public: $str";
}
public static function publicStaticMethod ($str)
{
return "public+static: $str";
}
private function privateMethod ($str)
{
return "private: $str";
}
private static function privateStaticMethod ($str)
{
return "private+static: $str";
}
protected function protectedMethod ($str)
{
return "protected: $str";
}
protected static function protectedStaticMethod ($str)
{
return "protected+static: $str";
}
}
TestklassTest.php
<?php
require_once './Testklass.php';
class TestklassTest extends PHPUnit_Framework_TestCase
{
public static function methodAsPublic ($class, $method)
{
$ref = new \ReflectionMethod($class, $method);
$ref->setAccessible(true);
$obj = (gettype($class) === 'object') ? $class : null;
return function () use ($class, $ref, $obj) {
$args = func_get_args();
return $ref->invokeArgs($obj, $args);
};
}
public function test_publicMethod ()
{
$method = self::methodAsPublic(new Testklass, 'publicMethod');
$actual = $method('$str');
$expected = 'public: $str';
$this->assertSame($expected, $actual);
}
public function test_publicStaticMethod ()
{
$method = self::methodAsPublic('Testklass', 'publicStaticMethod');
$actual = $method('$str');
$expected = 'public+static: $str';
$this->assertSame($expected, $actual);
}
public function test_privateMethod ()
{
$method = self::methodAsPublic(new Testklass, 'privateMethod');
$actual = $method('$str');
$expected = 'private: $str';
$this->assertSame($expected, $actual);
}
public function test_privateStaticMethod ()
{
$method = self::methodAsPublic('Testklass', 'privateStaticMethod');
$actual = $method('$str');
$expected = 'private+static: $str';
$this->assertSame($expected, $actual);
}
public function test_protectedMethod ()
{
$method = self::methodAsPublic(new Testklass, 'protectedMethod');
$actual = $method('$str');
$expected = 'protected: $str';
$this->assertSame($expected, $actual);
}
public function test_protectedStaticMethod ()
{
$method = self::methodAsPublic('Testklass', 'protectedStaticMethod');
$actual = $method('$str');
$expected = 'protected+static: $str';
$this->assertSame($expected, $actual);
}
}
当然だけどテスト用途以外に使ってはならない(戒め)。