Servizi statici e testabilità

6

Dove viene disegnata la linea figurata per l'utilizzo di servizi statici in un progetto? Sono uno studente della coop che lavora e impara a scrivere progetti .net MVC. Ho sviluppato cercando di attenermi a TDD. Nel mio progetto sto usando ninject per l'iniezione delle dipendenze. Ho scritto un abstract e una classe che li implementa per fare chiamate al servizio API alla nostra API interna. Non esiste ancora una libreria di classi per queste API, quindi sto scrivendo le mie cose.

In questo caso mi sto ritrovando a chiedermi perché sto usando classi non statiche per questo servizio API. Non ci sono informazioni sullo stato memorizzate per le chiamate API che sono IP validati. Tutti gli indirizzi per le posizioni delle chiamate sono memorizzati nel file di configurazione.

Non riesco a vedere come usare una classe statica qui renderebbe la prova più difficile. Puoi testare la classe statica per verificare che funzioni. Se ti trovi a dover utilizzare dati fittizi, puoi semplicemente prendere in giro l'oggetto che l'API dovrebbe restituire. Se ciò è impossibile a causa della progettazione del metodo, è altamente probabile che il metodo che stai testando stia cercando di fare molto.

Ritengo che quasi tutte le situazioni, in questo caso particolare, in cui il fatto che il servizio sia statico influenzerebbe il testing, si verificherebbero nel tentativo di manipolare gli oggetti restituiti; che dovrebbe essere estratto in un'estensione o in un metodo di utilità che potrebbe essere testato, quindi non ci dovrebbero essere problemi con la classe statica che influisce sul test.

C'è una buona ragione per non diventare statico che mi manca o qualcosa che riguarda il test unitario e l'iniezione che mi manca? Mi piacerebbe poter dire con certezza che usare l'elettricità statica è una buona idea in questo caso, ma sento che mi manca la conoscenza per farlo.

Un'altra domanda è stata collegata "È statico universalmente malvagio" che non è una mia domanda. So che la statica non è universalmente malvagia e ha il suo posto. La mia domanda è: dove è prudente utilizzare la statica e in quali circostanze un servizio astratto può essere meglio scritto come statico, senza causare problemi di testabilità.

    
posta Tenderdude 23.11.2016 - 19:56
fonte

2 risposte

8

I metodi statici sono problematici perché impediscono l'inserimento delle dipendenze per gli utenti di quel metodo statico.

In primo luogo, vorrei essere chiaro che questo non è sempre un problema. Se una funzione è pura (non mantiene lo stato tra le chiamate e non esegue alcun I / O), è sufficiente testarla direttamente una volta e quindi utilizzarla in un altro codice sapendo che funzionerà. Questo di solito si applica solo a piccoli metodi di utilità, o quando stai facendo una programmazione funzionale rigorosa.

Se il servizio fornito da quel metodo statico è più complesso, l'uso delle tecniche di iniezione delle dipendenze diventa desiderabile:

  • Se un metodo mantiene lo stato, non si vuole mantenere quello stato tra test differenti - sarebbe un tipo di accoppiamento che potrebbe oscurare i bug. Per lo meno, vorrete un meccanismo per (almeno temporaneamente) resettare lo stato per ogni test. Il modo più semplice per farlo è creare una nuova istanza della classe che include, che non è possibile con metodi statici e classi statiche.

  • Se il servizio interagisce con il mondo esterno o esegue qualsiasi I / O (a parte la registrazione), non lo desideri durante un test dell'unità.

    Consideriamo un servizio per inviare notifiche via email. Il sistema sottoposto a test dovrebbe inviare e-mail in determinate condizioni. Come lo metti alla prova? Configurare un account di posta elettronica di prova e verificare di aver ricevuto il messaggio previsto? Sì, ma sarebbe un test di integrazione. Per i test unitari, vorremmo solo assicurarci che il servizio email sia stato invocato con la configurazione corretta.

    Se riesci a intercettare la chiamata tramite un altro meccanismo piuttosto che sostituire il servizio tramite l'iniezione delle dipendenze, probabilmente è OK.

  • Se il servizio contiene una logica aziendale sostanziale che potrebbe cambiare frequentemente, non si desidera che i test non correlati vengano a mancare a causa di modifiche a tale logica. Nell'ambito di un test, la sostituzione della logica di business non correlata con gli stub renderà i test più robusti, supponendo che sia naturalmente testato altrove.

Le classi statiche hanno i loro usi, ma non dovrebbero essere la tua scelta predefinita. Solo quando è chiaramente non desiderabile avere un'istanza di quella classe se la si rende statica, il che accade quasi solo quando è meno di una classe e più di uno spazio dei nomi per i metodi statici.

    
risposta data 23.11.2016 - 20:30
fonte
0

Il test delle classi statiche può essere fatto con un trucco: progettare la classe statica in modo tale che sia in realtà una sorta di wrapper attorno a un'istanza: tutte le chiamate alla classe statica vengono inoltrate a un'istanza che esegue effettivamente il lavoro. Quindi aggiungi un metodo statico void SetInstanceForTesting(IInterfaceOfTheInstance instance) . Ho avuto questa idea dal libro di Mike Feather sul codice legacy.

    
risposta data 25.11.2016 - 09:27
fonte

Leggi altre domande sui tag