Récemment, j'étais TDDing une méthode d'usine. La méthode consistait à créer soit un objet simple, soit un objet enveloppé dans un décorateur. L'objet décoré peut être de plusieurs types, tous étendant StrategyClass.
Dans mon test, je voulais vérifier si la classe d'objet retourné était comme prévu. C'est facile quand un objet simple revient, mais que faire quand il est emballé dans un décorateur?
Je code en PHP afin que je puisse utiliser ext/Reflection
pour trouver une classe d'objet enveloppé, mais il me semblait être trop compliqué et quelque peu contre les règles de TDD.
Au lieu de cela, j'ai décidé d'introduire getClassName()
qui retournerait le nom de classe de l'objet lorsqu'il était appelé à partir de StrategyClass. Cependant, lorsqu'il est appelé depuis le décorateur, il renvoie la valeur retournée par la même méthode dans l'objet décoré.
Un code pour le rendre plus clair:
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();
}
}
Et un test 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
Mon point est le suivant: est-il acceptable d'introduire de telles méthodes, qui n'ont d'autre utilité que de faciliter les tests unitaires? D'une certaine manière, cela ne me semble pas juste.