Recientemente estaba TDDing un método de fábrica. El método consistía en crear un objeto simple o un objeto envuelto en un decorador. El objeto decorado podría ser de uno de varios tipos, todos extendiendo StrategyClass.
En mi prueba, quería comprobar si la clase del objeto devuelto es la esperada. Eso es fácil cuando el objeto simple regresó, pero ¿qué hacer cuando está envuelto dentro de un decorador?
Codifico en PHP para poder usarlo ext/Reflectionpara encontrar una clase de objeto envuelto, pero me pareció que era demasiado complicado, y de alguna manera contra las reglas de TDD.
En su lugar, decidí introducir getClassName()que devolvería el nombre de la clase del objeto cuando se llama desde StrategyClass. Sin embargo, cuando se llama desde el decorador, devolvería el valor devuelto por el mismo método en el objeto decorado.
Algún código para hacerlo más claro:
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();
}
}
Y una prueba 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
Mi punto aquí es: ¿está bien introducir tales métodos, que no tienen otro uso que hacer que las pruebas unitarias sean más fáciles? De alguna manera no me parece bien.