Crea un oggetto all'interno di un metodo

0

Supponiamo che il mio oggetto debba utilizzare un'API per comunicare con un dispositivo. La chiamata API di cui ho bisogno è Api.do_something ().

Quale sarebbe il modo migliore per risolverlo assumendo che io debba chiamarlo solo una volta? Sono propenso a utilizzare la terza opzione, ma non è l'iniezione della dipendenza davvero troppo di una seccatura quando ho solo bisogno di chiamarlo una volta? La soluzione più semplice è la prima, ma poi devo prendere in giro Api (). Do_something () ogni volta che il mio test usa do_stuff (). D'altra parte con l'iniezione di dipendenza devo comunque fornire un oggetto stub.

1)

class MyObject(object):
    def do_stuff():
        return Api().do_something()

2)

class MyObject(object):
    def __init__():
        self.api = Api()

    def do_stuff():
        return self.api.do_something()

3)

class MyObject(object):
    def __init__(api):
        self.api = api

    def do_stuff():
        return self.api.do_something()
    
posta iknownothing 21.06.2017 - 18:38
fonte

1 risposta

0

Ogni pezzo di codice (funzione, classe, metodo) ha due client:

  • l'altro codice che utilizza questo codice è il client principale

  • i test unitari sono client secondari

Durante la progettazione del codice, è necessario tenere in considerazione entrambi i clienti. Fare scelte progettuali che vanifichino completamente lo scopo per i clienti primari è inutile, ma fare spesso dei compromessi per rendere i test più facili ne vale la pena. Quando i test sono più semplici, è più probabile che tu scriva buoni test, il che rende indirettamente il tuo codice più solido e più facile da modificare in futuro.

L'iniezione delle dipendenze è una di queste cose che complica il tuo codice, ma che vale davvero per i test. Ogni volta che il tuo codice utilizza una variabile globale, i tuoi test diventano più fragili perché devono testare questa dipendenza implicita. La gestione esplicita delle dipendenze attraverso l'iniezione del costruttore è decisamente preferibile.

Nel tuo specifico esempio, le opzioni 1 e 2 sono fondamentalmente equivalenti: il MyObject istanzia la dipendenza Api stessa. Nell'opzione 3, si utilizza l'iniezione del costruttore per questa dipendenza. Pertanto, se stai testando MyObject , sarebbe preferibile scegliere l'opzione 3.

Se in realtà questa è solo una semplice classe che traduce le chiamate di metodo a questa API specifica, non ha alcun senso rendere configurabile l'API: MyObject è già intrinsecamente accoppiata all'API, MyObject rappresenta quell'API. In questo caso, la dipendenza dai client su MyObject dovrebbe essere invece soggetta all'iniezione di dipendenza.

    
risposta data 25.06.2017 - 12:17
fonte

Leggi altre domande sui tag