2009-04-27 76 views
6

我有一個呼叫到現有的Web服務的類。我的課程正確處理了有效的結果以及由Web服務生成的錯誤字符串。對Web服務的基本調用看起來像這樣(儘管這是簡化的)。如何爲Spring的WebServiceTemplate創建一個模擬對象?

public String callWebService(final String inputXml) 
{ 
    String result = null; 

    try 
    { 
    StreamSource input = new StreamSource(new StringReader(inputXml)); 
    StringWriter output = new StringWriter(); 

    _webServiceTemplate.sendSourceAndReceiveToResult(_serviceUri, input, new StreamResult(output)); 

    result = output.toString(); 
    } 
    catch (SoapFaultClientException ex) 
    { 
    result = ex.getFaultStringOrReason(); 
    } 

    return result; 
} 

現在我需要創建一些測試所有成功和失敗條件的單元測試。它無法調用實際的Web服務,所以我希望Spring-WS的客戶端有可用的模擬對象。有沒有人知道可用於WebServiceTemplate或任何相關類的模擬對象?我應該只是嘗試寫我自己的和修改我的類使用WebServiceOperations接口與WebServiceTemplate?

回答

7

邁克爾答案非常接近,但這裏是有效的例子。

我已經在單元測試中使用Mockito,所以我對庫很熟悉。然而,與我以前使用Mockito的經歷不同,簡單地嘲笑返回結果並沒有幫助。我需要做兩件事來測試所有的用例:

  1. 修改存儲在StreamResult中的值。
  2. 拋出SoapFaultClientException。

首先,我需要認識到,我不能用Mockito模擬WebServiceTemplate,因爲它是一個具體的類(如果這是必需的,您需要使用EasyMock)。幸運的是,對Web服務sendSourceAndReceiveToResult的調用是WebServiceOperations接口的一部分。這需要對我的代碼進行更改,以期望WebServiceOperations與WebServiceTemplate相對。

以下代碼支持其中一個結果是在StreamResult參數返回的第一用例:

private WebServiceOperations getMockWebServiceOperations(final String resultXml) 
{ 
    WebServiceOperations mockObj = Mockito.mock(WebServiceOperations.class); 

    doAnswer(new Answer() 
    { 
    public Object answer(InvocationOnMock invocation) 
    { 
     try 
     { 
     Object[] args = invocation.getArguments(); 
     StreamResult result = (StreamResult)args[2]; 
     Writer output = result.getWriter(); 
     output.write(resultXml); 
     } 
     catch (IOException e) 
     { 
     e.printStackTrace(); 
     } 

     return null; 
    } 
    }).when(mockObj).sendSourceAndReceiveToResult(anyString(), any(StreamSource.class), any(StreamResult.class)); 

    return mockObj; 
} 

用於第二使用情況下的支撐是相似的,但需要一個異常的投擲。以下代碼創建一個包含faultString的SoapFaultClientException。在faultcode是我測試的代碼處理Web服務請求使用:

private WebServiceOperations getMockWebServiceOperations(final String faultString) 
{ 
    WebServiceOperations mockObj = Mockito.mock(WebServiceOperations.class); 

    SoapFault soapFault = Mockito.mock(SoapFault.class); 
    when(soapFault.getFaultStringOrReason()).thenReturn(faultString); 

    SoapBody soapBody = Mockito.mock(SoapBody.class); 
    when(soapBody.getFault()).thenReturn(soapFault); 

    SoapMessage soapMsg = Mockito.mock(SoapMessage.class); 
    when(soapMsg.getSoapBody()).thenReturn(soapBody); 

    doThrow(new SoapFaultClientException(soapMsg)).when(mockObj).sendSourceAndReceiveToResult(anyString(), any(StreamSource.class), any(StreamResult.class)); 

    return mockObj; 
} 

更多的代碼可能需要這兩種使用情況,但他們爲我的目的工作。

4

實際上我不知道是否存在預配置的模擬對象,但我懷疑是否配置了所有的「失敗條件」,因此您可以爲您的JUnit測試創建一個特殊的Spring ApplicationContext替代或使用模擬框架,它並不難:-)

我使用的Mockito模擬框架的例子(鍵入它快),但EasyMock或您首選的模擬框架應該做得一樣好

package org.foo.bar 
import java.util.ArrayList; 
import java.util.List; 
import org.junit.Before; 
import org.junit.Test; 
import static org.mockito.Mockito.*; 
import static org.junit.Assert.*; 

public class WebserviceTemplateMockTest { 

    private WhateverTheInterfaceIs webServiceTemplate; 
    private TestClassInterface testClass; 
    private final String inputXml = "bar"; 


    @Test 
    public void testClient(){ 
     // 
     assertTrue("foo".equals(testClass.callWebService(inputXml)); 
    } 

    /** 
    * Create Webservice Mock. 
    */ 
    @Before 
    public void createMock() { 
     // create Mock 
     webServiceTemplate = mock(WhateverTheInterfaceIs.class); 
     // like inputXml you need to create testData for Uri etc. 
     // 'result' should be the needed result data to produce the 
     // real result of testClass.callWebService(...) 
     when(webServiceTemplate.sendSourceAndReceiveToResult(Uri, inputXml, new StreamResult(output))).thenReturn(result); 
     // or return other things, e.g. 
     // .thenThrow(new FoobarException()); 
     // see mockito documentation for more possibilities 
     // Setup Testclass 
     TestClassImpl temp = new TestClassImpl(); 
     temp.setWebServiceTemplate(generatedClient); 
     testClass = temp; 
    } 
} 
+0

Mockito +1。 – CoverosGene 2009-04-27 20:06:30

相關問題