[英]Unit Testing Methods that make WCF Service Call?
首先嘗試進行任何實際的單元測試。 我有一個WPF客戶端應用程序,該應用程序從WCF服務中的方法接收數據。 這些方法調用直接從客戶端應用程序中的視圖模型進行:
public string LoadArticle()
{
MyServiceClient msc = new MyServiceClient();
return Article = msc.GetArticle(_UserName);
}
然后,我有一個測試項目,在其中新建一個ViewModel,然后調用我的方法:
[TestMethod]
public void LoadArticleTestValid()
{
var articleViewModel = new ArticleViewModel("Thomas");
string userName = "Thomas";
string expected = "Article 1";
var actual = articleViewModel.LoadArticle(userName);
etc.
}
顯然,此測試將失敗,因為客戶端應用程序無法訪問該服務以調用LoadArticle
。 如何解決這種情況? 我應該使用依賴注入並將某種IMyService接口傳遞給構造函數,而不是在ViewModel中創建MyServiceClient還是以某種方式模擬服務?
這就是問題:
MyServiceClient msc = new MyServiceClient();
這在ArticleViewModel
和MyServiceClient
之間創建了緊密的耦合。 為了僅對 ArticleViewModel
進行單元測試,需要對這種依賴關系進行ArticleViewModel
。 如果存在IMyServiceClient
則可以將其提供給類:
public ArticleViewModel
{
private IMyServiceClient ServiceClient { get; set; }
public ArticleViewModel(IMyServiceClient serviceClient)
{
this.ServiceClient = serviceClient;
}
// etc.
}
然后,該類中的代碼不會創建新的服務客戶端,而只會使用該屬性中的那個。
然后,在單元測試中,您將創建IMyServiceClient
模擬,在該模擬上定義預期的行為,並將其提供給要測試的對象。 如何執行取決於模擬庫。 Rhino Mocks中的一個簡單示例如下所示:
// arrange
var serviceClient = MockRepository.GenerateMock<IMyServiceClient>();
serviceClient.Stub(c => c.GetArticle(Arg<string>.Is.Anything)).Return("Article 1");
var model = new ArticleViewModel(serviceClient);
// act
var result = model.LoadArticle("Thomas");
// assert
Assert.AreEqual("Article 1", result);
這里的想法是,單元測試僅測試LoadArticle
方法,而不測試該方法調用的依賴項。 這些依賴性提供了預期的行為,並根據這些預期的行為檢查了結果。
注意:沒有什么可以阻止單元測試提供MyServiceClient
的實際實現,而不是提供模擬。 單元測試項目只需要配置該服務即可使用。 (單元測試項目是應用程序宿主,它們可以具有App.config
文件。)這將是集成測試而不是單元測試,但是可以對結果進行相同的聲明。
是的,我認為您是對的,我建議使用IMyService的構造函數參數,您可以使用該參數將模擬注入到對象中進行測試。
進一步! 我建議不要使用自動生成的服務客戶端。 如果將代碼復制並粘貼到自己的類中,則可以使其實現IMyService,並有效地隱藏它使用WCF,直接進入DB或是真實代碼中的模擬對象的事實。
這將允許您將模擬注入WPF中以進行UI測試
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.