2012-12-10 77 views
2

我正在使用MEF將我的對象組合在一起,並在測試某些未導出到MEF容器但依賴於將對象實例注入屬性設置器的類時遇到問題MEF。測試依賴於MEF注入的非導出類

例如,請考慮以下兩個視圖模型

public class ViewModelA 
{ 
    [Import] 
    internal IAdmin AdminService 
    { 
     get; 
     private set; 
    } 

    public ViewModelA() 
    { 
     CompositionInitializer.SatisfyImports(this); 
    } 

    //constructor for testing 
    internal ViewModelA(IAdmin adminService) 
    { 
     this.AdminService = adminService; 
    } 

    public void DoSomething() 
    { 
     this.AdminService.SetCurrentWindow(new ViewModelB()); 
    } 
} 


public class ViewModelB 
{ 
    [Import] 
    internal IAdmin AdminService 
    { 
     get; 
     private set; 
    } 

    [Import] 
    internal IAnotherService AnotherServiceService 
    { 
     get; 
     private set; 
    } 

    public ViewModelB() 
    { 
     CompositionInitializer.SatisfyImports(this); 
    } 

    public void DoAnotherThing() 
    { 
     //Does something with the properties injected via MEF 
    } 

} 

這些類沒有導出到MEF容器,這樣我靠打電話CompositionInitializer.SatisfyImports(this)迫使依賴進口。

我想爲ViewModelA創建一個測試,用於檢查調用DoSomething的結果,IAdmin.SetCurrentWindow方法被ViewModelB的一個實例調用一次。爲了滿足這個要求,我爲ViewModelA創建了一個構造函數重載,它將IAdmin作爲參數,我還使用Moq和Silverlight單元測試框架創建了以下測試。

[TestMethod] 
    public void DoSomethingStandard_CallsSetCurrentWindowWithViewModelB() 
    { 
     var adminServiceMock = new Mock<IAdmin>(); 
     var vmA = new ViewModelA(adminServiceMock.Object); 
     vmA.DoSomething(); 
     adminServiceMock.Verify(ad => ad.SetCurrentWindow(It.IsAny<ViewModelB>()), Times.Exactly((1))); 
    } 

我的問題是,測試運行調用ViewModelA.DoSomething當實例化一個ViewModelB這又拋出了一個

System.Reflection.ReflectionTypeLoadException:無法加載請求的類型中的一種或多種。檢索LoaderExceptions屬性以獲取更多信息。

這是因爲ViewModelB構造函數調用CompositionInitializer.SatisfyImports(this),但在我的測試項目中沒有設置MEF容器。

關於如何最好地測試這種情況有什麼想法嗎?或者代碼如何重構以使其可測試?

回答

1

我認爲你唯一能做的就是將你的[Import] ed屬性改爲公開給setter公開,並直接設置實例。你不應該在單元測試中擔心MEF。

這個thread進入它更深入。