타사 코드를 포장하여 소비자를 단위 테스트하는 유일한 솔루션입니까?


13

단위 테스트를 수행하고 있으며 클래스 중 하나에서 메소드 중 하나에서 메일을 보내야하므로 생성자 주입을 사용하여 Zend_MailZend 프레임 워크 에있는 클래스 인스턴스를 주입합니다 .

이제 일부 사람들은 라이브러리가 충분히 안정적이며 자주 변경되지 않으면 랩핑 할 필요가 없다고 주장합니다. 따라서 그것이 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클래스 를 조롱해야합니다 . 또한 클래스가 추상화가 아닌 생성에 의존하기 때문에 Dependency Inversion 원칙을 위반합니다 Logger.

이제 Logger줄 바꿈없이 어떻게 격리 테스트 할 수 Zend_Mail있습니까?!

코드는 PHP로되어 있지만 답변 할 필요는 없습니다. 이것은 언어 별 기능보다 더 많은 디자인 문제입니다.


인터페이스를 사용해야합니까? PHP는 오리 타이핑을 지원하지 않습니까?
케빈 클라인

@ kevincline 잘 나는 PHP를 가장 많이 사용하는 언어이기 때문에 PHP를 사용했지만 실제로는 PHP에만 국한되지 않는 문제에 대한 일반적인 해결책을 찾고 있습니다.
Songo

답변:


21

항상 인터페이스 뒤에 타사 유형 및 메소드를 래핑하려고합니다. 이것은 지루하고 고통 스러울 수 있습니다. 때로는 코드 생성기를 작성하거나 도구를 사용하여이를 수행 할 수 있습니다.

그러나 코드 전체에서 라이브러리 메서드 나 형식을 사용하려는 유혹을받지 마십시오. 우선 단위 테스트 작성에 문제가 있습니다. 그런 다음 라이센스가 변경되거나 타사에서 지원하지 않는 플랫폼으로 가고 싶을 때 해당 유형과 종속성이 다른 모든 클래스와 관련이 있음을 알 수 있습니다.

타사 공급 업체를 빠르게 변경할 수있는 기능은 큰 이점입니다.


4
"당신이 작성하지 않은 것은"조금입니다. 표준 또는 플랫폼의 일부인 라이브러리는 랩핑하기 어렵습니다. 예를 들어 모든 .NET 구성 요소를 래핑하고 싶지 않을 것입니다. 래퍼가 인터페이스를 통과하거나 코드가 생성되면 테스트 작성에 거의 이점이 없습니다. 논리가있는 경우 (통합 호출 등) 테스트가 도움이 될 수 있습니다.
Ben

3
마지막 문장으로 찬성.
Blrfl

1
올바르게 리팩토링하면 라이브러리 기능의 반복적 인 사용이 서비스 클래스에 반영됩니다. 미리 정의 할 필요가 없습니다.
케빈 클라인

3
-1 : 타사 라이브러리가 표준화 된 API가있는 서비스를 제공하는 경우를 제외하고는 시간이 많이 걸리며 코드를 복제함으로써 유지 관리 효율성 만 떨어집니다. 또한 YAGNI.
Michael Borgwardt

1
@MichaelBorgwardt : 물론,이 경우 표준 API가 래퍼가되어 라이브러리를 쉽게 교체 할 수 있습니다.
Blrfl
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.