2014-10-29 139 views
2

我正在運行單元測試視圖模型的以下問題。如何在ViewModel中單元測試OnPropertyChanged事件處理程序

在我的項目中,有多個視圖模型(比如說A,B,C和D)。 視圖模型A是主視圖模型,它處理來自視圖模型B,C和D的PropertyChanges,然後更新主視圖。

大多數方法/在查看模型的屬性單元以外的事件處理方法處理來自B,C和D.

所述的PropertyChanged事件例如可測試:

public A() 
{ 
    b.PropertyChanged += b_PropertyChanged; 
    c.PropertyChanged += c_PropertyChanged;   
} 


protected void b_PropertyChanged(object sender, PropertyChangedEventArgs e) 
{ 
    //process something based on the e.PropertyName 
    //might call some private or protected methods here to help with the processing 
    switch(e.Property) 
    { 
    case "SearchResults": 
     SearchResults = b.SearchResults; 
     break; 
    } 
} 

如何可以我去測試b_PropertyChanged而不公開?

+0

更改'b'或'c'中的屬性?有什麼問題? – Sheridan 2014-10-29 15:34:56

+0

你想要測試的是什麼?視圖模型A中的某些狀態是否在viewmodel B等中更改了特定的屬性?給出一個例子,說明如果b_PropertyChanged方法是公開的,你的Asserts將會在你的單元測試中出現。 – user469104 2014-10-29 15:37:37

+0

是 - A將處理B或C中的任何屬性更改。 – aggietech 2014-10-29 15:38:54

回答

2

你可以創建一個包裝類來做到這一點(見下文)只需在它的位置使用可測試類,它將執行代碼。

public class Program 
{ 
    private static void Main(string[] args) 
    { 
     TestableProgram2 tp = new TestableProgram2(); 
     tp.b_PropertyChanged(new Program(), "bang"); 
    } 
} 

public class Program2 
{ 
    protected void b_PropertyChanged(object sender, string e) 
    { 
     Debug.Write(e); 
    } 
} 

public class TestableProgram2 : Program2 
{ 
    public new void b_PropertyChanged(object sender, string e) 
    { 
     e = "altered";  // here to demonstrate this code is entered. 
     base.b_PropertyChanged(sender, e); 
    } 
} 
+1

那麼,爲了測試目的創建類的子類? – aggietech 2014-10-29 15:43:17

+0

是的,我不得不這樣做很多次,總是感到厭煩,但它的工作原理。我只是做了一個小小的編輯,使樣本實際上工作:)你可以告訴它的工作原理,因爲調試將輸出改變的字符串,你可以刪除它,因爲它只是在那裏展示其通過公共方法到基地。 – 2014-10-29 15:51:27

+0

保護無效b_PropertyChanged應該是虛擬的權利? – aggietech 2014-10-29 15:57:04

1

在這些情況下,習慣上將功能移出事件處理程序並移入可以獨立調用的自己的方法。你可以嘗試這樣的事:

protected void b_PropertyChanged(object sender, PropertyChangedEventArgs e) 
{ 
    YourNewMethod(e.Property); 
} 

public void YourNewMethod(string propertyName) 
{ 
    switch(propertyName) 
    { 
     case "SearchResults": 
      SearchResults = b.SearchResults; 
      break; 
    } 
} 

測試時,您現在可以調用YourNewMethod測試該功能。

+0

好吧 - 應該將NewMethod設置爲public,以便它可以進行單元測試嗎? – aggietech 2014-10-29 15:55:32

+0

您可以將它移出如果它的保護你仍然不能調用它,它將不得不公開,它不是很好。包裝更清潔,不涉及改變對象結構。這並不是說移出事件處理程序中的代碼isn'這是一個好主意:) – 2014-10-29 16:04:52

+0

是的抱歉...這是複製和粘貼你;;)現在更新。 – Sheridan 2014-10-29 16:11:13

相關問題