2012-04-12 60 views
3

我正在尋找驗證給定方法(單元)執行正確邏輯的最佳方法。驗證方法調用和參數沒有嘲諷框架

在這種情況下,我具有類似於方法:

public void GoToMyPage() 
{ 
    DispatcherHelper.BeginInvoke(() => 
    { 
     navigationService.Navigate("mypage.xaml", "id", id); 
    }); 
} 

navigationService是一個接口,INavigationService的注入嘲笑版本。現在,我想在我的單元測試中驗證,使用正確的參數調用Navigate(...)

但是,在Windows Phone上IL發射不支持某種程度,其中一個模擬框架可以創建一個動態代理並分析呼叫。爲此我需要手動分析這個。

一個簡單的解決方案是將Navigate(...)方法中調用的值保存在公共屬性中,並在單元測試中檢查它們。然而,這對於所有不同類型的模擬和方法來說都是非常煩人的。

所以我的問題是,是否有更聰明的方式來創建使用C#功能(如委託)的分析調用,而無需使用基於反射的代理,而不必手動保存調試信息?

+0

爲什麼你不想用反射來獲取參數? – Tigran 2012-04-12 12:52:04

+0

正如我寫的,Windows Phone不支持創建基於反射的動態代理。 – 2012-04-12 13:03:07

+0

你說的是Emiting,但我說的是在運行時只使用反射來讀取數據,而不是*生成/注入。 – Tigran 2012-04-12 13:05:15

回答

3

我的方法是手動創建INavigationService的可測試實現,該實現捕獲調用和參數,並允許您稍後驗證它們。

public class TestableNavigationService : INavigationService 
{ 
    Dictionary<string, Parameters> Calls = new Dictionary<string, Parameters>(); 

    public void Navigate(string page, string parameterName, string parameterValue) 
    { 
     Calls.Add("Navigate" new Parameters()); // Parameters will need to catch the parameters that were passed to this method some how 
    } 

    public void Verify(string methodName, Parameters methodParameters) 
    { 
     ASsert.IsTrue(Calls.ContainsKey(methodName)); 
     // TODO: Verify the parameters are called correctly. 
    } 
} 

這可能然後在您的測試像使用:

public void Test() 
{ 
    // Arrange 
    TestableNavigationService testableService = new TestableNavigationService(); 
    var classUnderTest = new TestClass(testableService); 

    // Act 
    classUnderTest.GoToMyPage(); 

    // Assert 
    testableService.Verify("Navigate"); 
} 

我還沒有想過這個問題被傳遞到方法的參數,但我想這是一個良好的開端。

+0

這種方法的潛力是實現上的代碼生成,然後將其編譯爲正常 - 在編譯時爲您提供模擬框架的靈活性。 – 2012-04-12 14:11:16