2012-11-23 13 views
5

Ho una classe (consente di chiamare A) che:Come testare una classe che consuma un servizio Web?

  • Nel costruttore prende un config e basato su di esso, crea un mozzicone di un servizio Web e memorizza un riferimento ad esso in un settore privato.
  • Ha alcuni metodi che chiamano metodi web e alcune cose in mezzo.

ho iniziato a creare una prova di unità che:

  • crea un'istanza di una classe A con una configurazione manichino.
  • Attraverso la riflessione, esso inietta lo stub del servizio Web.

Anche se questo servizio Web ha molti metodi.

  • Devo prendere in giro tutti (in ogni test, con dati diversi)?
  • O forse dovrei creare un altro livello che incapsula solo i metodi Web che vengono utilizzati?
  • Oppure c'è un altro approccio?
+1

Grazie! Non sapevo su quella caratteristica! – Janek

risposta

5

Dovresti creare un'interfaccia wrapper attorno al tuo webservice, e fare in modo che la tua classe sotto test prenda una dipendenza da tale interfaccia, piuttosto che direttamente sul webservice; puoi quindi prendere in giro l'interfaccia. Solo fare in modo che quell'interfaccia esponga i metodi del servizio web che trovi interessanti. Questo è noto come modello di facciata ed è dettagliato here.

Senza avere la minima idea di ciò che si sta testando, puntare a qualcosa di simile:

public interface IWebserviceWrapper 
{ 
    Whatever DoStuff(int something); 
} 

public class WebserviceWrapper : IWebserviceWrapper 
{ 
    private WebService _theActualWebservice; 

    public WebserviceWrapper(Webservice theService) 
    { 
     _theActualWebService = theService; 
    } 

    public Whatever DoStuff(int something) 
    { 
     return _theActualWebservice.DoSomething(something); 
    } 

} 

Poi il test sarebbe simile a questa (in questo caso, utilizzando MOQ)

public void Test_doing_something() 
{ 
    Mock<IWebserviceWrapper> _serviceWrapperMock = new Mock<IWebserviceWrapper>(); 

    _serviceWrapperMock.SetUp(m => m.DoStuff(12345)).Returns(new Whatever()); 

    var classUnderTest = new ClassUnderTest(_serviceWrapperMock.Object); 

    var result = classUnderTest.Dothings(12345); 

    Assert.Whatever.... 

} 
+0

Grazie. Quindi fondamentalmente proponi la soluzione numero 2 da quelli che ho elencato. Ma allora che ne dici di testare questo strato extra? Penso che ad un certo punto dovrò prendere in giro tutti i metodi, giusto? Perché altrimenti dovrei assumere che un metodo sotto test usa solo un sottoinsieme fisso di metodi web disponibili - che non è un'ipotesi corretta quando testare l'unità, è corretto? – Janek

+0

Opzione 2, si. Non dovresti mai davvero dover testare l'interfaccia o la classe del wrapper, dato che tutto ciò che sta facendo è delegare qualsiasi chiamata effettuata al servizio di terze parti.Quindi, unit test che classe significa unità testare il servizio web, e che non è più un test unitario, è un test di integrazione. Inoltre, utilizzando "solo un sottoinsieme fisso di metodi web disponibili" è esattamente il punto della facciata –

+0

Grazie Greg. Ciò ha senso! – Janek

1

Risposta breve Sì :). Risposta lunga, dovresti usare una specie di lib di derisione per esempio: http://code.google.com/p/mockito/ e nel tuo test di unità prendi in giro lo stub WS e lo passi alla classe testata. Questa è la via della forza :)

1

Quando collaudi una classe, vuoi sempre assicurarti di testare solo quella classe e non includere le sue dipendenze. Per fare ciò, dovrai prendere in giro il tuo WS per fare in modo che restituisca dati fittizi quando vengono chiamati i metodi. A seconda dei tuoi scenari, non devi prendere in giro TUTTI i metodi per ogni test, direi solo quelli che vengono utilizzati.

Per un esempio su beffardo, si può leggere questo articolo: http://written-in-codes.blogspot.ca/2011/11/unit-tests-part-deux.html

Problemi correlati