OOP per il test delle unità: il buono, il brutto e il cattivo

6

Recentemente ho letto la guida pdf di Miško Hevery su scrivendo codice verificabile in cui ha dichiarato che dovresti limitare le tue istanze di classi nei tuoi costruttori. Capisco che è quello che dovresti fare perché ti permette di prendere facilmente in giro oggetti che vengono inviati come parametri alla tua classe. Ma quando si tratta di scrivere codice reale, spesso finisco con cose del genere (l'esempio è in PHP usando Zend Framework ma penso che sia auto esplicativo):

class Some_class
{
    private $_data;

    private $_options;

    private $_locale;

    public function __construct($data, $options = null)
    {
        $this->_data = $data;

        if ($options != null) {
            $this->_options = $options;
        }

        $this->_init();
    }

    private function _init()
    {
        if(isset($this->_options['locale'])) {
            $locale = $this->_options['locale'];

            if ($locale instanceof Zend_Locale) {
                $this->_locale = $locale;
            } elseif (Zend_Locale::isLocale($locale)) {
                $this->_locale = new Zend_Locale($locale);
            } else {
                $this->_locale = new Zend_Locale();
            }
        }
    }
}

Secondo la mia comprensione della guida di Miško Hevery, non dovrei installare Zend_Local nella mia classe, ma spingerlo attraverso il costruttore (che può essere fatto attraverso l'array di opzioni nel mio esempio).

Mi sto chiedendo quale sarebbe la migliore pratica per ottenere la massima flessibilità per la disattivazione di questo codice e anche, se voglio allontanarmi da Zend Framework.

Grazie in anticipo

    
posta JF Dion 07.03.2011 - 22:17
fonte

2 risposte

1

Hai assolutamente ragione, non devi codificare a caldo un riferimento a Zend nel metodo.

Hai bisogno di una cucitura, uno strato di astrazione, in modo che tu possa passare Zend o qualsiasi altra struttura. Non so se PHP abbia un concetto di interfacce, ma quelle sono un modo popolare per astrarre le implementazioni dal codice.

Consiglio il libro di Michael Feathers "Lavorare efficacemente con il codice legacy" per una discussione dettagliata sull'argomento.

    
risposta data 07.03.2011 - 22:59
fonte
1

Questo deriva da un bias Java / C #; potrebbe non avere senso in PHP.

Per rendere il codice più facile da testare senza rimuovere il framework Zend:

Se puoi, inserisci direttamente "Zend_Locale". Personalmente trovo l'array opzionale un po 'brutto; nasconde le dipendenze della tua classe. Avrei un parametro locale senza optional nel ctor. Il DI Framework (o il creatore dell'oggetto se lo stai facendo manualmente) è responsabile della compilazione dei dettagli.

Se non si riesce a iniettare, e la logica necessaria per capire come generare "Zend_Locale" non è propriamente la responsabilità di "Some_class", inietterei una fabbrica. Ciò renderà un po 'più semplice il test delle unità (a seconda della complessità della logica) dato che puoi facilmente dare uno stub.

Se vuoi allontanarti da Zend Framework allora devi guardare tutti gli elementi di framework Zend che usi e generare un wrapper per loro con l'interfaccia anche per te nel codice client e ovunque tu abbia un "nuovo Zend_ blah "allora è necessario iniettare l'istanza o iniettare una fabbrica.

    
risposta data 07.03.2011 - 23:03
fonte

Leggi altre domande sui tag