2013-01-11 75 views
0

我開發使用CookComputing XML-RPC.net應用單元測試/嘲諷XML-RPC.net電話

我的問題是如何單元調用外部RPC方法的測試方法。

如果我們把網站上的例子:

//This is the XML rpc Proxy interface 
[XmlRpcUrl("http://www.cookcomputing.com/xmlrpcsamples/RPC2.ashx")] 
public interface IStateName : IXmlRpcProxy 
{ 
    [XmlRpcMethod("examples.getStateName")] 
    string GetStateName(int stateNumber); 
} 


public class MyStateNameService 
{ 
    public string GetStateName(int stateNumber) 
{ 
     IStateName proxy = XmlRpcProxyGen.Create<IStateName>(); 
     return proxy.GetStateName(stateNumber); 
    } 
} 

我們怎樣纔能有效地測試IStateName的結果,而無需實際擊中 http://www.cookcomputing.com/xmlrpcsamples/RPC2.ashx

我認爲一個良好的開端將是對MyStateNameService回吐構造一個IStateName,並在IStateName上傳遞一個虛假(或模擬?)實例...

我很想測試它的實際內容 - 例如僞裝響應SE從端點,並返回,不知怎的,不僅驗證GetStateName調用服務...

編輯

我並不想測試服務爲這樣的內容,而且什麼我的類與它做。

因此,例如,說的迴應是:

<?xml version="1.0"?> 
<methodResponse> 
    <params> 
    <param> 
     <value><string>My State Name</string></value> 
    </param> 
    </params> 
</methodResponse> 

我會想「假」該響應一些如何測試MyStateNameService.GetStateName實際返回的「我的國家名稱」

+0

爲什麼你要測試的內容?當然,一旦它被命中'IStateName'代理它不再是你的應用程序的關注。不要測試外部代碼,這取決於編寫庫的人! –

+0

對不起......我將編輯問題以使其更清晰。請參閱編輯問題 – Alex

+0

我仍然不確定這一點。糾正我,如果我錯了,但你不直接處理XML,你調用代理上的一個方法,它會創建一個請求,並將它發送到爲RPC提供服務的任何地方。響應返回到代理,然後解析輸出並提供給您?在這種情況下,你無法控制XML解析,圖書館的代理類可以完成它,那麼爲什麼要測試它呢? –

回答

0

你的問題在於這裏應用的單例模式。

XmlRpcProxyGen.Create<IStateName>(); 

所以你的想法與使用依賴注入(通過構造函數)是一個好的開始。 (您是否使用IoC容器?)

接下來是爲IStateName服務創建模擬/僞造/存根。 這可以通過許多方式來實現。

使用動態嘲弄的系統可以爲您節省一些工作的其他自動/動態模擬框架,但你需要了解他們的用法。

使用NUnit的,NSubstitute和修改MyStateNameService經典AAA測試的例子:

class MyStateNameService 
{ 
    private readonly IStateName _remoteService; 
    public MyStateNameService(IStateName remoteService) 
    { 
    // We use ctor injection to denote the mandatory dependency on a IStateName service 
    _remoteService = remoteService; 
    } 

    public string GetStateName(int stateNumber) 
    { 
    if(stateNumber < 0) throw new ArgumentException("stateNumber"); 
    // Do not use singletons, prefer injection of dependencies (may be IoC Container) 
    //IStateName proxy = XmlRpcProxyGen.Create<IStateName>(); 
    return _remoteService.GetStateName(stateNumber); 
    } 
} 

[TestFixture] class MyStateNameServiceTests 
{ 
    [Test] 
    public void SomeTesting() 
    { 
    // Arrange 
    var mockService = Substitute.For<IStateName>(); 
    mockService.GetStateName(0).Returns("state1"); 
    mockService.GetStateName(1).Returns("state2"); 

    var testSubject = new MyStateNameService(mockService); 


    // Act 
    var result = testSubject.GetStateName(0); 

    // Assert 
    Assert.AreEqual("state1", result); 

    // Act 
    result = testSubject.GetStateName(1); 

    // Assert 
    Assert.AreEqual("state2", result); 

    // Act/Assert 
    Assert.Throws<ArgumentException>(() => testSubject.GetStateName(-1)); 
    mockService.DidNotReceive().GetStateName(-1); 

    /* 
     MyStateNameService does not do much things to test, so this is rather trivial. 
     Also different use cases of the testSubject should be their own tests ;) 
    */ 


    } 

} 
+0

是的,我知道*我需要做什麼,只是在這裏尋找更深入的答案....我可能會使用moq – Alex

+0

我可以給你代碼測試與NSubstitute MyStateNameService,不知道多少關於moq雖然... – sanosdole

+0

這很好,我主要概念,使用任何庫。我不是'給我一個codez'類型的用戶;-) – Alex