最近、ファクトリーメソッドをTDDしていました。その方法は、単純なオブジェクト、またはデコレータでラップされたオブジェクトを作成することでした。装飾されたオブジェクトは、いずれもStrategyClassを拡張するいくつかのタイプのいずれかです。
私のテストでは、返されたオブジェクトのクラスが期待どおりかどうかを確認したかった。単純なオブジェクトosが返されたときは簡単ですが、デコレータでラップされたらどうしますか?
ext/Reflection
ラップされたオブジェクトのクラスを見つけるために使用できるようにPHPでコーディングしますが、物事を複雑にしすぎているようで、TDDのルールにやや反対しています。
代わりにgetClassName()
、StrategyClassから呼び出されたときにオブジェクトのクラス名を返すように導入することにしました。ただし、デコレータから呼び出された場合は、装飾されたオブジェクトの同じメソッドによって返された値を返します。
より明確にするためのいくつかのコード:
interface StrategyInterface {
public function getClassName();
}
abstract class StrategyClass implements StrategyInterface {
public function getClassName() {
return \get_class($this);
}
}
abstract class StrategyDecorator implements StrategyInterface {
private $decorated;
public function __construct(StrategyClass $decorated) {
$this->decorated = $decorated;
}
public function getClassName() {
return $this->decorated->getClassName();
}
}
そして、PHPUnitテスト
/**
* @dataProvider providerForTestGetStrategy
* @param array $arguments
* @param string $expected
*/
public function testGetStrategy($arguments, $expected) {
$this->assertEquals(
__NAMESPACE__.'\\'.$expected,
$this->object->getStrategy($arguments)->getClassName()
)
}
//below there's another test to check if proper decorator is being used
ここでの私のポイントは次のとおりです。ユニットテストを簡単にする以外に用途のないそのようなメソッドを導入しても大丈夫ですか?どういうわけかそれは私には正しく感じられません。