In Unit Testing, perché dovrei creare un repository due volte?

10

L'altro giorno stavo leggendo un po 'di Unit Testing e ho visto alcuni esempi in cui le persone creano un'interfaccia repository (cioè IExampleRepository ) e poi creano il repository reale ( public class ExampleRepository : IExampleRepository ) e un repository da utilizzare per l'unità test ( FakeExampleRepository : IExampleRepository ).

Nel IExampleRepository stavano implementando gli stessi metodi di ExampleRepository , tuttavia con query Linq differenti.

Qual è esattamente l'obiettivo qui? Ho pensato che una parte dell'unità di test del codice è assicurarsi che un metodo funzioni correttamente? Ma quando uso due query totalmente diverse, una per "reale" e una per il test, quanto senso ha il test?

    
posta jao 08.04.2013 - 10:51
fonte

4 risposte

8

Uno degli obiettivi del test unitario è testare solo una cosa alla volta, cioè una singola classe e un metodo. Se il repository stesso non è sotto test, normalmente lo si deriderebbe in qualche modo in modo da testare la logica nel metodo / classe.

Detto questo, devi testare anche con un repository "reale" *, ma questo normalmente verrebbe eseguito in un test di integrazione / sistema

* ovviamente reale come in repo impostato per il test, si spera non ad es. il DB di produzione.

    
risposta data 08.04.2013 - 10:56
fonte
5

Sono d'accordo con le due risposte di jk. e Jan Hudec - danno alcune informazioni veramente buone. Ma ho pensato di aggiungere un po '.

La tua prima domanda ("Qual è esattamente l'obiettivo qui?") è importante. Nel caso che stai descrivendo, il vero obiettivo è testare le classi che utilizzano l'interfaccia IExampleRepository , non testare le implementazioni del repository. La creazione di FakeExampleRepository ti consente di testare quelle classi client senza preoccuparti dei dettagli della classe reale del repository.

Questo è particolarmente vero se l'oggetto che stai tentando di impostare rende difficile il test (ad esempio, accede al file system, chiama un webservice o parla con un database). Usando le interfacce (e altre tecniche simili), si mantiene basso l'accoppiamento. Pertanto, la classe X deve solo conoscere l'interfaccia e non è necessario conoscere i dettagli dell'implementazione. L'obiettivo è assicurarsi che la classe X stia facendo la cosa giusta.

Il derisione (o lo stub, la contraffazione ... ci sono differenze sfumate) è un potente strumento per il test unitario e TDD. Ma può essere un problema creare manualmente e mantenere queste implementazioni. Pertanto, la maggior parte delle lingue ora ha librerie di derisione per aiutare. Dato che stai utilizzando C #, ti consigliamo di Moq perché è semplice e molto potente. Quindi puoi testare l'interfaccia senza accumulare codice aggiuntivo per le implementazioni fittizie.

    
risposta data 08.04.2013 - 18:46
fonte
5

What is exactly the objective here?

Isolamento.

L'idea di un'unità prova a testare la unità di codice più piccola possibile. Lo fai isolandolo da tutti gli altri codici di produzione nel test.

Creando classi false l'unico codice di produzione è la classe sotto test.

Se crei un repository fasullo e il test fallisce, sai che il problema è con il code-under-test. Questo ti dà il vantaggio della diagnosi gratuitamente.

Dai un'occhiata ai framework di isolamento (come Moq come suggerito da @Allan) per essere in grado di generare questi falsi rapidamente per impostare le condizioni di prova e usarle per affermare contro.

    
risposta data 11.04.2013 - 18:15
fonte
4

Ci sono tre motivi per cui potresti voler fornire un'istanza di simulazione a unit test:

  1. Vuoi limitare lo scopo del test, in modo che il test non sia influenzato da bug nel depndee, probabilmente perché non è ancora finito o non è stabile o non vuoi che i bug di qualcun altro influenzino i tuoi test .
  2. Il dipendente è complicato da configurare. Ad esempio, il livello di accesso ai dati viene spesso deriso, perché quello reale richiede l'impostazione di un database di test. Devi ancora testare il vero livello di accesso ai dati, ma puoi limitare l'impostazione costosa quando esegui il debug di altre cose.
  3. Per verificare che la classe dipendente reagisca correttamente a vari tipi di errori, fornisci una versione fittizia che restituisce tutti i tipi di risposte errate. Perché molte modalità di errore sono piuttosto difficili da riprodurre, ma dovrebbero comunque essere testate.
risposta data 08.04.2013 - 15:46
fonte

Leggi altre domande sui tag