Я делаю модульное тестирование, и в одном из моих классов мне нужно отправить письмо от одного из методов, поэтому, используя инъекцию конструктора, я внедряю экземпляр Zend_Mail
класса, который находится в среде Zend.
Теперь некоторые люди утверждают, что если библиотека достаточно стабильна и не будет часто меняться, то нет необходимости ее оборачивать. Если предположить, что Zend_Mail
это стабильно и не изменится и полностью соответствует моим потребностям, тогда мне не понадобится обертка для него.
Теперь взгляните на мой класс, Logger
который зависит от Zend_Mail
:
class Logger{
private $mailer;
function __construct(Zend_Mail $mail){
$this->mail=$mail;
}
function toBeTestedFunction(){
//Some code
$this->mail->setTo('some value');
$this->mail->setSubject('some value');
$this->mail->setBody('some value');
$this->mail->send();
//Some
}
}
Тем не менее, модульное тестирование требует, чтобы я тестировал по одному компоненту за раз, поэтому мне нужно издеваться над Zend_Mail
классом. Кроме того, я нарушаю принцип инверсии зависимости, поскольку мой Logger
класс теперь зависит от конкреции, а не абстракции.
Теперь, как я могу тестировать Logger
в изоляции без упаковки Zend_Mail
?
Код написан на PHP, но ответы не должны быть. Это скорее проблема дизайна, чем особенность языка
Ответы:
Вы всегда хотите обернуть сторонние типы и методы за интерфейс. Это может быть утомительно и больно. Иногда вы можете написать генератор кода или использовать инструмент для этого.
Но не поддавайтесь искушению использовать библиотечные методы или типы в вашем коде. Для начала у вас будут проблемы с написанием юнит-тестов. Затем лицензия изменится, или вы захотите перейти на платформу, не поддерживаемую третьей стороной, и обнаружите, что эти типы и зависимости переплетены между всеми вашими другими классами.
Возможность быстрой смены сторонних поставщиков является огромным преимуществом.
источник