2012-02-15 133 views
3

位A NUnit的/ nMock /單元測試noobie問題:與NUnit的單元測試和nMocks

我試圖單元測試這個類。

我已經創建了一個模擬器,因爲我想知道從「getCurrencyRates」返回的值,以便可以基於該數據創建測試。

所以我創建了這個對象的模擬(只是爲了能夠知道返回的匯率)。

...但現在我也想調用這個類的其他一些方法。

我應該:

一)以某種方式實現從模擬對象的實際方法(甚至不知道這是可能的) B)重構,以便只有Web服務調用是在它自己的對象,並創建一個模擬那個 c)別的東西?

public class CurrencyConversion : ICurrencyConversion 
{ 
    public decimal convertCurrency(string fromCurrency, string toCurrency, decimal amount) 
    { 

     CurrencyRateResponse rates = getCurrencyRates(); 
     var fromRate = getRate(rates, fromCurrency); 
     var toRate = getRate(rates, toCurrency); 

     decimal toCurrencyAmount = toRate/fromRate * amount; 

     return toCurrencyAmount; 
    } 


    public int addNumbers(int i, int j) 
    { 
     return i + j; 

    } 

    public decimal getRate(CurrencyRateResponse rates, string fromCurrency) 
    { 

     if (rates.rates.ContainsKey(fromCurrency)) 
     { 
      return rates.rates[fromCurrency]; 
     } 
     else 
     { 
      return 0; 
     } 
    } 
    public CurrencyRateResponse getCurrencyRates() 
    { 
     HttpWebRequest webRequest = GetWebRequest("http://openexchangeerates.org/latest.json"); 

     HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse(); 
     string jsonResponse = string.Empty; 
     using (StreamReader sr = new StreamReader(response.GetResponseStream())) 
     { 
      jsonResponse = sr.ReadToEnd(); 
     } 

     var serializer = new JavaScriptSerializer(); 
     CurrencyRateResponse rateResponse = serializer.Deserialize<CurrencyRateResponse>(jsonResponse); 

     return rateResponse; 

    } 
    public HttpWebRequest GetWebRequest(string formattedUri) 
    { 
     // Create the request’s URI. 
     Uri serviceUri = new Uri(formattedUri, UriKind.Absolute); 

     // Return the HttpWebRequest. 
     return (HttpWebRequest)System.Net.WebRequest.Create(serviceUri); 
    } 
} 

回答

3

CurrencyConverter此刻做兩件事情:轉換貨幣(這是好的),並調用外部服務來獲取數據(這是壞的)。你想要你的課程有single,很容易確定的責任。您的代碼將更清潔,更易於管理,而且在這方面重要的是 - 更具可測試性。

重構您的數據(通過構造注射例如)提供方法(getCurrencyRates)給外部服務(類)和inject到您的轉換器對象。

另外,爲什麼NMocks?它不再被積極開發(最近的更新似乎是4-6 years ago),人們可能會認爲它不像現代框架那樣易於使用,如FakeItEasyMoq

+0

我選擇nMock是因爲它在我正在使用的nUnit書中提到過。有什麼限制?我發現你只能模擬一個接口 - http://stackoverflow.com/questions/131806/mocking-classes-that-arent-interfaces – iKode 2012-02-15 08:49:50

2

你會想做類似b)的事情。如果你正在測試一個對象,你不想嘲笑對象本身,但它的依賴。

您要模擬的依賴關係是對Web服務的調用,因爲在nunit測試中放入真正的Web服務調用將違反單元測試的內容,也是實施的噩夢。

創建涉及webserice呼叫

ICurrencyRateService 
{ 
    CurrencyRateResponse GetCurrencyRates() 
} 

,然後讓所有的webservicey代碼爲實現該目標部分的接口。

應該允許您測試ConvertCurrency。這也意味着你的對象之間有更好的分離關係,你有一個調用Web服務的對象和一個計算對象。