Я тестирую параметр, отправленный в обработчик обработанных событий. Параметр является объектом подтипа «Событие», который сам содержит некоторые данные, вложенные в него. Я хочу протестировать Событие, и его подструктура соответствует данным фикстуры, которые я внедрил в код с помощью различных макетов.
Я могу достаточно легко протестировать «верхний уровень» события: имя класса и простые атрибуты, такие как строка имени события. Я также могу проверить, что атрибут содержит тот же объект, который, как мне кажется, неявно проверяет всю субструктуру объекта.
У меня проблема в том, что некоторая подструктура в более сложном примере вызывает сбой теста, но он не имеет значения, поэтому я хочу выбрать вишню специфические свойства субструктуры, а не только идентичность — сравните весь объект.
Я чувствую, что что-то упускаю в утверждениях атрибута: как получить доступ к параметру, который «с» относится к переменной. Затем я мог бы передать его в некоторые методы assert, такие как attributeEqualTo, которые требуют, чтобы тестируемый элемент был передан. Возможно, их просто нельзя использовать в беглом случае, который я использую?
Упрощенный код:
class MyEventData{
public $thing1;
public $thing2;
}
class MyEvent{
public $data;
}
// An event gets fired containing this in the tests
$eventData = new MyEventData(1,2);
$this->eventMock->expects($this->exactly(3))
->method('fire')
->with(
$this->logicalAnd(
// THIS WORKS OK
$this->isInstanceOf('\MyApp\MyEvents\SomeEvent'),
// THIS WORKS OK
$this->attributeEqualTo ('name', SomeEvent::EVENT_NAME),
// THIS WORKS in simplified cases only
$this->attributeEqualTo ('data', $eventData),
// HOW DO I GET THE "WITH" PARAMETER CONTEXT "INTO" THE THIRD PARAMETER?
$this->assertAttributeInstanceOf('\MyApp\MyEvents\MyEventData', 'data', -classOrObject- ),
// Then how can I test with attribute data.thing1 == 1 and data.thing2 = 2
)
);
У меня это работает, используя callback
ограничение, но такое ощущение, что я сейчас сошёл с пути и потерял силу PHPUnit — кажется, я больше не могу использовать помощники утверждений здесь.
например Если накопленные тесты возвращают false, я не получаю никаких подробностей в выходном журнале за исключением «Ожидание не выполнено для … и принято указанным обратным вызовом».
$this->callback(function($subject){
$b = true;
// I tried using this constraint but can't access (autoload) this class? So is it not supposed to be used directly?
//$c = new PHPUnit_Framework_Constraint_IsInstanceOf('\MyApp\MyEvents\MyEventData');
// return $c->matches(subject);
// this is the right assert, but it doesn't return the result, so I cannot use it in a callback constraint.
\PHPUnit_Framework_Assert::assertAttributeInstanceOf('\MyApp\MyEvents\MyEventData', 'data', $subject);
// This works but seems very "Manual"$b = $b && get_class($subject->data) == '\MyApp\MyEvents\MyEventData';
$b = $b && $subject->data->thing1 == 1;
$b = $b && $subject->data->thing2 == 1;
return $b;
})
Других решений пока нет …