В документации PHPUnit в разделе, посвященном mocks, объясняется, как прикрепить макет-объект внутри тестируемого класса:
...
$observer = $this->getMockBuilder('Observer')
->setMethods(array('update'))
->getMock();
...
$subject = new Subject('My subject');
$subject->attach($observer);
$subject->doSomething();
В моем случае я хочу протестировать метод Subject
. Этот метод создает много таких объектов:
public function myMethod() {
for($i = 0; $i < 10; $i++) {
$this->collection []= new Observer(/* some data */);
}
}
Как я могу издеваться над всеми наблюдателями?
Вы не можете издеваться над классом. new
оператор получит определение класса на основе вашего автозагрузчика или того, что уже является памятью. Вы не можете динамически заменить определение класса в своем тесте.
Вы могли бы создать альтернативное определение класса для Observer
, которое определило бы поведение и, по сути, было бы "макетным" классом, который вы использовали бы. Проблема заключается в том, что если вы запустите этот тест с помощью тестов для фактического класса Observer
, вы получите ошибку, которую вы не можете переопределить. И все становится очень сложным.
Ваш пример довольно упрощен, но я бы проверил его, убедившись, что все элементы в Subject::collection
являются экземплярами Observer
. Если бы были какие-то конкретные данные, которые я знал о каждом наблюдателе, я бы использовал фактические методы Observer
для их проверки. (Однако это не очень хорошая практика).
Если ваш метод создает объекты, а затем вызывает методы на них, я бы серьезно пересмотрел ваш дизайн. Я бы myMethod
как минимум на два метода. Один, который прикрепляет объект Observer
который вы можете использовать в своем тесте, чтобы передать макет объекта в с. А другой, который называет методы Observer
который будет остальной myMethod
функции myMethod
которой у вас нет.