2012-02-20 65 views
3

我的代碼非常類似於此,但無法計算出我如何測試事件處理程序是否發生。驗證執行的事件處理程序代碼

public class MyClass : MyAbstractClass 
{ 
    IFileSystem FileSystem; 

    public MyClass(IFileSystem myFileSys) 
    { 
    FileSystem = myFileSys; 
    FileSystem.EventHit += new EventHandler(FileSystem_EventHit); 
    } 

    public void FileSystem_EventHit(object sender, EventArgs e) 
    { 
    //Testing base.OnOutput is not possible which I wont go into 
    base.OnOutput("EventHit"); 
    } 
} 

測試代碼是在這裏:

[Test] 
    public void DoSomething_WhenCalled_EventFired() 
    { 
     var mock = new Moq.Mock<IFileSystem>(); 

     MyClass plugin = new MyClass (mock.Object); 

     mock.Object.DoSomething(); 

     mock.Raise(x => x.EventHit += null, new EventArgs()); 

     //Verify/Assert that MyClass handled and did something in the event handler 

    } 
+0

你可以提供詳細信息WRT base.OnOutput,也許它是可測試的? – 2012-02-20 13:47:12

+0

MyAbstractClass是遺留的,因此MyClass也是遺留下來的,因此它很混亂,需要大量的設置才能測試,所以我希望有一些方法可以測試,而無需驗證base.OnOutput – Jon 2012-02-20 13:51:35

+0

常見的場景;回顧性編寫單元測試。我不知道任何捷徑。每當遇到這種情況,我都會重新構造代碼,以便它可以進行單元測試。 – 2012-02-20 13:56:42

回答

0

由於驗證事件處理程序中的某些內容意味着嘗試測試遺留代碼,所以我選擇的選項是測試事件是從具體類型中觸發的事件,而不是模擬。

[Test] 
public void DoSomething_WhenCalled_EventFired() 
{ 

    FileSystem fs = new FileSystem(mock.Object, timerMock.Object); 

    bool WasItHit = false; 
    fs.EventHit += delegate { WasItHit = true; }; 

    fs.DoSomething(); //This should call the event 

    Assert.IsTrue(WasItHit); 
} 
1

我能想到的最簡單的方法是隻需添加自己的處理程序中的測試方法,這應該足夠我會想到什麼?

[Test] 
    public void DoSomething_WhenCalled_EventFired() 
    { 
     var mock = new Moq.Mock<IFileSystem>(); 
     bool isHit = false; 

     mock.EventHit += (s, e) => 
     { 
      isHit = true; 
     }; 

     MyClass plugin = new MyClass (mock.Object); 

     mock.Object.DoSomething(); 

     mock.Raise(x => x.EventHit += null, new EventArgs()); 

     Assert.IsTrue(isHit); 

    } 
+1

這將聲明模擬引發的事件,它不會證實MyClass.FileSystem_EventHit被調用或驗證發生了什麼結果。 – 2012-02-20 13:45:48

0

您需要爲事件處理程序調用的結果注入任何被調用的模擬並進行驗證。你的評論說你不能測試base base.OnOutput,但在我看來,這正是你需要做的。

+0

這就是問題所在!抽象類和大多數MyClass是遺留代碼,它是一個噩夢來測試 – Jon 2012-02-20 13:50:00

0

基本測試調用方法的事實不是有效的測試用例,您應該測試方法背後的邏輯/行爲。顯然,對於給定的事件處理函數,沒有什麼可以測試的,這就是爲什麼一個任務看起來不平凡。

試試用幾句話寫出你想要測試什麼樣的測試用例。例如

MyClass的切換的狀態下進入State==Hit同時 FileSystem.EventHit事件。

+0

我同意,但MyClass充當輸入/輸出類的類,所以東西進來調用DoSomething,它會觸發事件並執行輸出 – Jon 2012-02-20 13:53:19

+0

它是什麼做輸出,喬恩?如果是另一個依賴項,那麼模擬MyClass或基類用來執行輸出的依賴項,並驗證是否使用該依賴項進行了輸出調用。 – 2012-02-20 14:02:51

+0

是的,我會做的,但它的所有遺留代碼,是一個噩夢設置 – Jon 2012-02-20 14:13:24

0

要做到這一點,您可能需要MyClass中的一個標誌來指示事件發生。我知道,這只是爲了運行測試的目的,但有時候有這樣的好事。

相關問題