У меня есть объект состояния, который расширяет базовый абстрактный класс, который реализует SplSubject.
Однако это состояние затем передается методу уведомления наблюдателей — мои модульные тесты и IDE жалуются на связанный тип.
abstract class TQ_Type implements \SplObserver
{
public function update(TQ_State $tq_state)
{
...
}
}
abstract class TQ_State implements \SplSubject
{
public function __construct()
{
$this->observers = new SplObjectStorage;
}
public function attach(TQ_Type $observer)
{
$this->observers->attach($observer);
}
public function detach(TQ_Type $observer)
{
$this->observers->detach($observer);
}
public function notify()
{
foreach ($this->observers as $observer)
{
$observer->update($this);
}
}
}
Следующий тест дает: PHP Фатальная ошибка: объявление TQ_State :: attach () должно быть совместимо с SplSubject :: attach (SplObserver $ SplObserver)
class TQTypeStandardAppealTest extends PHGUnit_Internal
{
private $under_test;
public function setUp()
{
$this->under_test = new TQ_Type_StandardAppeal();
}
public function test_pending_standard_appeal_tq_approval_hits_states_notify_method()
{
$state = Mockery::mock('TQ_State_Pending')->makePartial();
$state->shouldReceive('get_event')
->withNoArgs()
->andReturn('Approve');
$this->under_test->update($state);
}
}
Я наследую эти и те производные классы, которые являются предметом модульных тестов …
Является ли это проблемой, когда издевательство не соблюдает иерархию объекта, над которым оно издевается
NB. Я использовал здесь частичное макетирование, так как фактический макет возвращает Mockery \ CompositeExpectation, но я рассмотрю это позже.
Сумасшедший от моего имени.
Проще говоря, они должны уважать контракты интерфейса, поэтому они должны иметь SplObserver и SplSubject. Любое дальнейшее требование ограничить способность объекта не правильного типа запускать метод обновления наблюдателя должно обрабатываться в этом методе.
Других решений пока нет …