2013-04-18 20 views
7

La mia classe in prova ha questo metodoMockito modello per una chiamata di servizio Web Primavera

public SomeWebServiceResponse callDownstream(SomeWebServiceRequest request) { 
    return (SomeWebServiceResponse) super.callService(request); 
} 

il metodo super-è solo una chiamata a primavera WS per effettuare la chiamata - in forma semplificata

response = getWebServiceTemplate().marshalSendAndReceive(this.getBaseURL(), 
    request); 
return response; 

Quando scrivo un test di unità, ho provato a effettuare una chiamata al servizio web effettivo. Non sono chiaro come deriderlo o piuttosto cosa dovremmo prendere in giro.

Dovrei caricare una risposta di esempio dal filesystem e cercare una stringa in esso - in tal caso sto solo testando il caricamento dei file.

La chiamata effettiva è in classe base e so che non possiamo prendere in giro solo quel metodo. Qualche indicazione?

risposta

8

Spring fornisce inoltre servizi per i server di servizio Web di simulazione e le richieste dei client. Il capitolo 6.3 nel Spring WS manual mostra come si fa il mocking.

La funzione di simulazione di Spring WS modifica il comportamento del modello di servizio Web, quindi è possibile chiamare tale metodo nella super classe: tale metodo chiamerebbe quindi il server di servizio Spring Mock.

Ecco uno unit test campione con il server del servizio finto Primavera:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration({"classpath:spring-ws.xml"}) 
public class SetStatusFromSrsTemplateTest { 
    @Autowired 
    private WebServiceTemplate wsTemplate; 

    @Before 
    public void setUp() throws Exception { 
     mockServer = MockWebServiceServer.createServer(wsTemplate); 
    } 

    @Test 
    public void testCall() { 
     SomeWebServiceRequest sampleRequest = new SomeWebServiceRequest(); 
     // add properties to the sampleRequest... 
     Source expectedPayload = new ResourceSource(new ClassPathResource("exampleRequest.xml")); 
     Source expectedResponse = new ResourceSource(new ClassPathResource("exampleResponse.xml")); 
     mockServer.expect(payload(expectedPayload)).andRespond(withPayload(expectedResponse)); 
     instance.callDownStream(sampleRequest); 
     mockServer.verify(); 
    } 
} 

L'esempio sopra farà il server del servizio finta aspettarsi esattamente un richiesta con la data payload e (se il carico utile ricevuto corrisponda al previsto carico utile) rispondono con il carico utile di risposta dato.

Tuttavia, se si desidera solo verificare che il metodo nella super-classe venga effettivamente chiamato durante il test e se non si è interessati allo scambio di messaggi in seguito a tale chiamata, è necessario utilizzare Mockito.

Se si desidera utilizzare Mockito, suggerirei alla spia (vedere anche la risposta di Kamlesh). Per esempio.

// Decorates this with the spy. 
MyClass mySpy = spy(this); 
// Change behaviour of callWebservice method to return specific response 
doReturn(mockResponse).when(mySpy).callWebservice(any(SomeWebServiceRequest.class)); 
// invoke the method to be tested. 
instance.callDownstream(request); 
// verify that callWebService has been called 
verify(mySpy, times(1)).callWebService(any(SomeWebServiceRequest.class)); 
+0

Siamo spiacenti per il mio commento precedente. Penso di non aver capito bene il problema. Fornirò un esempio su come eseguire i test unitari con il server di servizio Spring Mock. –

+0

Mocking di tutto il servizio Web, incluso l'invio e la ricezione di un messaggio (primo esempio di codice) è in realtà più di un test di unità: si tratta di un test di integrazione, come indicato anche nel manuale Spring. Se hai solo bisogno di un test unitario, dovresti seguire Mockito (secondo esempio di codice). – Justus

0

Come ha detto @Duncan, la composizione con l'iniezione di dipendenza sarebbe un modo per andare se possibile e quindi prendere in giro tale dipendenza.

Se non è possibile, è possibile simulare in modo selettivo i metodi della classe in prova utilizzando il mockito spy.