2014-01-31 63 views
2

我有一個方法,我要寫單元測試。方法的簡化版本:在C中嘲弄局部變量#

public static bool IsUpdateAvailable() 
{ 
    Version installedVersion = Util.GetInstalledVersionFromRegistry(); 
    Version availableVersion = Util.GetAvailableVersionFromRemote(); 

    bool isRemoteVersionNewer = IsVersionNewer(installedVersion, availableVersion); 

    return isRemoteVersionNewer; 
} 

所以,問題是讓兩個局部變量(installedVersion,availableVersion)讀出他們的價值不是來自真正的來源(在這種情況下,從註冊表和網絡),但是從某種假冒源。我無法修改上述方法。我試圖瞭解如何通過使用Moq或Microsoft Fakes來嘲弄這兩個變量。我在互聯網上搜索,但無法找到一些相關的示例代碼。 那麼我怎麼可以嘲笑上述方法的局部變量並測試該方法?

+0

在不同的命名空間比你測試的類是Util.GetInstalledVersionFromRegistry()? – Jimmy

+0

@Jimmy是的Util.GetInstalledVersionFromRegistry()是在一個不同的命名空間 – Arterius

+0

只是放棄了我所問,這是不可能嘲笑這一點,沒有改變一些代碼,檢查我的答案。 – Jimmy

回答

1

我也建議依賴注入,如果你可以做到的話。如果你不能解決這個問題,你可以使用墊片。

http://msdn.microsoft.com/en-us/library/hh549176(v=vs.110).aspx#bkmk_static_methods

你提到你不能做任何修改功能。我提出了一個改變,但是你會發現它並不重要。

(代碼沒有編譯或測試)

public static Version GetInstalledVersionFromRegistry() 
{ 
    return Util.GetInstalledVersionFromRegistry(); 
} 

public static Version GetVersionFromRemote() 
{ 
    return Util.GetAvailableVersionFromRemote(); 
} 

public static bool IsUpdateAvailable() 
{ 
    Version installedVersion = GetInstalledVersionFromRegistry(); 
    Version availableVersion = GetVersionFromRemote(); 

    bool isRemoteVersionNewer = IsVersionNewer(installedVersion, availableVersion); 

    return isRemoteVersionNewer; 
} 

測試使用墊片

using (ShimsContext.Create()) 
{ 
     ShimYourclass.GetInstalledVersionFromRegistry=()=>new Version(); 
     ShimYourclass.GetInstalledVersionFromRegistry=()=>new Version(); 

     //test your class here  
     Yourclass.IsUpdateAvailable(); 
} 
4

每個靜態和硬編碼依賴關係都是這個問題。 儘量避免靜電,儘可能將其分類不好的擺在首位。 開發將某些東西標記爲靜態的真實參數,而不是因爲R#告訴了你。

如何解決這個問題是通過依賴注入。你必須通過參數注入依賴關係使其可測試。

ctor(Version installedVersion, Version availableVersion) { 
    // Maybe store them in private fields. 
} 

public bool IsUpdateAvailable() 
{ 
    bool isRemoteVersionNewer = IsVersionNewer(installedVersion, availableVersion); 

    return isRemoteVersionNewer; 
} 

我想你現在看到,你不必嘲笑變量本身。您可以使用不同的輸入創建對象的不同實例。一個用你的Util.方法構建對象,另一個用單元測試的測試數據構建對象。

1

一般來說靜態的東西都不會嘲弄,有一些框架可以做到,但是你可以很容易地在這條路線上創建一個混亂的混亂。

在你是特殊情況下,如果這些參數是真正全球適用於你的應用程序,你可能需要一個AmbientContext。這將允許從靜態容器到處訪問它們,但仍允許嘲笑測試。

雖然TimmKrause說,通常在大多數時間通過這些參數會更好。