Как издеваться над классом, созданным внутри тестируемого класса?

0

В документации 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 */);
    }
}

Как я могу издеваться над всеми наблюдателями?

Теги:
unit-testing
phpunit

1 ответ

1

Вы не можете издеваться над классом. new оператор получит определение класса на основе вашего автозагрузчика или того, что уже является памятью. Вы не можете динамически заменить определение класса в своем тесте.

Вы могли бы создать альтернативное определение класса для Observer, которое определило бы поведение и, по сути, было бы "макетным" классом, который вы использовали бы. Проблема заключается в том, что если вы запустите этот тест с помощью тестов для фактического класса Observer, вы получите ошибку, которую вы не можете переопределить. И все становится очень сложным.

Ваш пример довольно упрощен, но я бы проверил его, убедившись, что все элементы в Subject::collection являются экземплярами Observer. Если бы были какие-то конкретные данные, которые я знал о каждом наблюдателе, я бы использовал фактические методы Observer для их проверки. (Однако это не очень хорошая практика).

Если ваш метод создает объекты, а затем вызывает методы на них, я бы серьезно пересмотрел ваш дизайн. Я бы myMethod как минимум на два метода. Один, который прикрепляет объект Observer который вы можете использовать в своем тесте, чтобы передать макет объекта в с. А другой, который называет методы Observer который будет остальной myMethod функции myMethod которой у вас нет.

  • 0
    Я пришел к такому выводу, но я не хочу создавать много методов attach () во многих классах. На самом деле, я не хочу адаптировать свой код к инструментам модульного тестирования.
  • 1
    Тебе не нужно это делать. Вы можете использовать либо абстрактный базовый класс, либо черту, чтобы указать метод attach (). Удаление нового оператора из класса не адаптирует ваш код к инструменту модульного тестирования. Это следует за хорошей дизайнерской практикой. Когда я создаю экземпляр Subject, я могу не знать, что Observer появится вместе. Обозреватель может ретранслировать на внешнюю систему, которую в моем конкретном случае использования я не хочу использовать. Или я могу захотеть изменить, какой Observer используется в моем случае использования. Из-за нового оператора я должен использовать Observer, и у меня нет выбора. Дизайн менее гибкий.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню