其實測試是不應該測 protected 以及 private method 的,但有時候為了重構,原生程式碼東西拆不夠細導致同一個 public method 執行超多的 inner method,你要在測試該 public method 中測試所有 private method 是相當痛苦的,今天來探討一下如何用 Reflection 去測試 private 的內容
<?php class Chan { private $privateName = 'A'; private static $privateStaticName = 'B'; private function privateFoo($name = null) { if ($name !== null) { return $name; } return $this->privateName; } private static function privateStaticFoo($name = null) { if ($name !== null) { return $name; } return self::$privateStaticName; } }
這是一個叫 Chan 的 class,他包含了一般跟 static method 以及 property,現在逐步示範怎麼導出 private method 結果
使用 privateFoo
$chan = new Chan(); $reflection = new \ReflectionClass($chan); $method = $reflection->getMethod('privateFoo'); $method->setAccessible(true); echo $method->invoke($chan), PHP_EOL; // A echo $method->invokeArgs($chan, array('C')), PHP_EOL; // C
這個範例中沒帶參數會返回 A,有帶參數會返回參數值
使用 privateFoo 並影響預設 property
$chan = new Chan(); $reflection = new \ReflectionClass($chan); $method = $reflection->getMethod('privateFoo'); $method->setAccessible(true); $property = $reflection->getProperty('privateName'); $property->setAccessible(true); $property->setValue($chan, 'D'); echo $method->invoke($chan), PHP_EOL; // D
我們利用了 getPropery
這個方法變動了預設的 privateName 內容
使用 privateStaticFoo
$chan = new Chan(); $reflection = new \ReflectionClass($chan); $method = $reflection->getMethod('privateStaticFoo'); $method->setAccessible(true); echo $method->invoke($chan), PHP_EOL; // B echo $method->invokeArgs($chan, array('E')), PHP_EOL; // E $property = $reflection->getProperty('privateStaticName'); $property->setAccessible(true); $property->setValue('F'); echo $method->invoke($chan), PHP_EOL; // F
基本上用法差不多,只有 invokeArgs
的时候不用傳物件進去,但測試過後其實傳也可以
沒有留言:
張貼留言