Il wrapping di un codice di terze parti è l'unica soluzione per testare l'unità dei suoi consumatori?


13

Sto facendo unit test e in una delle mie classi ho bisogno di inviare una mail da uno dei metodi, quindi usando l'iniezione del costruttore ho iniettato un'istanza di Zend_Mailclasse che si trova nel framework Zend.

Ora alcune persone sostengono che se una biblioteca è abbastanza stabile e non cambierà spesso, non è necessario avvolgerla. Quindi supponendo che Zend_Mailsia stabile e non cambierà e soddisfi completamente le mie esigenze, quindi non avrò bisogno di un involucro per questo.

Ora dai un'occhiata alla mia classe Loggerche dipende da 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
   }        
}

Tuttavia, il test unitario richiede che io collauda un componente alla volta, quindi devo prendere in giro la Zend_Mailclasse. Inoltre, sto violando il principio di inversione di dipendenza poiché la mia Loggerclasse ora dipende dalla concrezione e non dall'astrazione.

Ora come posso testare Loggerin isolamento senza avvolgere Zend_Mail?!

Il codice è in PHP, ma le risposte non devono essere. Questo è più un problema di progettazione che una caratteristica specifica della lingua


Devi usare un'interfaccia? PHP non supporta la tipizzazione anatra?
Kevin Cline,

@kevincline ho usato PHP perché è il linguaggio che utilizzo di più, ma in realtà sto cercando una soluzione generale al problema non limitata al solo PHP.
Songo,

Risposte:


21

Volete sempre avvolgere tipi e metodi di terze parti dietro un'interfaccia. Questo può essere noioso e doloroso. A volte puoi scrivere un generatore di codice o usare uno strumento per farlo.

Ma non essere tentato di utilizzare i metodi o i tipi di libreria in tutto il codice. Per cominciare, avrai difficoltà a scrivere unit test. Quindi una licenza cambierà, o vorrai andare su una piattaforma non supportata da terze parti e scoprirai che quei tipi e dipendenze si sono intrecciati dentro e intorno a tutte le altre tue classi.

La possibilità di cambiare rapidamente fornitori di terze parti è un enorme vantaggio.


4
"Tutto ciò che non è stato scritto da te" è un po 'troppo. Le librerie che fanno parte dello standard o della piattaforma sono difficili da avvolgere. Probabilmente non vorrai avvolgere tutti i componenti .NET, ad esempio. Se i wrapper passano semplicemente attraverso le interfacce o generano codice, ho riscontrato pochi vantaggi nella scrittura dei test. Se c'è della logica lì dentro (combinando chiamate, ecc.) I test possono essere utili.
Ben

3
Eseguito l'upgrade per l'ultima frase.
Blrfl,

1
Se esegui il refactoring in modo corretto, qualsiasi uso ripetitivo delle strutture della biblioteca verrà considerato in una classe di servizio. Non è necessario definirlo in anticipo.
Kevin Cline,

3
-1: Tranne nei casi in cui la libreria di terze parti fornisce un servizio per il quale esiste un'API standardizzata, si tratta di un enorme spreco di tempo e ridurrà la manutenibilità solo con un codice duplicato. Inoltre, YAGNI.
Michael Borgwardt,

1
@MichaelBorgwardt: Certo, ma in tal caso, l'API standard diventa il wrapper e puoi scambiare facilmente le librerie.
Blrfl,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.