Ostatnio TDD stosowałem metodę fabryczną. Metoda polegała na utworzeniu zwykłego obiektu lub obiektu owiniętego dekoratorem. Udekorowany obiekt może być jednego z kilku typów rozszerzających StrategyClass.
W moim teście chciałem sprawdzić, czy klasa zwracanego obiektu jest zgodna z oczekiwaniami. To proste, gdy powróci zwykły obiekt, ale co zrobić, gdy jest zawinięty w dekoratorze?
Piszę w języku PHP, aby móc ext/Reflection
znaleźć klasę zawiniętego obiektu, ale wydawało mi się, że jest to zbyt skomplikowane i nieco przypomina zasady TDD.
Zamiast tego zdecydowałem się wprowadzić getClassName()
, która zwróci nazwę klasy obiektu, gdy zostanie wywołana ze StrategyClass. Jednak wywołany z dekoratora zwróci wartość zwróconą tą samą metodą w dekorowanym obiekcie.
Niektóre kody, aby to wyjaśnić:
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();
}
}
I 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
Chodzi mi o to: czy można wprowadzić takie metody, które nie mają innego zastosowania niż ułatwienie testów jednostkowych? Jakoś mi to nie pasuje.