2009-07-07 68 views
2

我想寫一些代碼涉及事件的單元測試。因爲我需要隨意舉辦活動,所以我決定依靠RhinoMocks爲我做這件事,然後確保提出的事件結果如預期的那樣(當他們點擊一個按鈕時,值應該改變一個可預測的方式,在這個例子中,物體的高度應該減小)犀牛嘲笑調用,而不是記錄在NUnit

所以,我做了一些研究並意識到我需要事件提升器來處理相關事件。然後就像調用eventraiser.Raise()一樣簡單;我們很好。

用於獲得一個事件加註我已經寫爲被如下(C#編寫的)(更多或更少的複製直脫淨)

  using (mocks.Record()) 
     { 
      MyControl testing = mocks.DynamicMock<MyControl>(); 
      testing.Controls.Find("MainLabel",false)[0].Click += null; 
      LastCall.IgnoreArguments(); 
      LastCall.Constraints(Rhino.Mocks.Constraints.Is.NotNull()); 
      Raiser1 = LastCall.GetEventRaiser(); 
     } 

我然後測試其作爲在播放模式中的代碼。

  using (mocks.Playback()) 
     { 
      MyControl thingy = new MyControl(); 
      int temp=thingy.Size.Height; 
      Raiser1.Raise(); 
      Assert.Greater(temp, thingy.Size.Height); 
     } 

問題是,當我通過NUnit運行這些測試時,它失敗了。它在線上引發異常testing.Controls.Find(「MainLabel」,false)[0] .Click + = null;其中抱怨嘗試將null添加到事件偵聽器。具體而言,「System.NullReferenceException:對象引用未設置爲對象的實例」

現在,我瞭解到,Mocks.Record標題下的任何代碼都不會實際被調用,它會產生期望用於播放中的代碼調用。但是,這是第二次出現這樣的問題(第一個問題涉及更復雜的類/案例)在NUnit中出現的代碼實際上是正常調用而不是創建期望的地方。我很好奇,如果有人能指出我做錯了什麼。或者解決核心問題的另一種方法。

回答

3

我不確定,但如果您沒有在MyControl中使事件變爲虛擬狀態,您可能會收到該行爲。如果方法,事件或屬性不是虛擬的,那麼我不認爲DynamicMock可以用記錄和回放版本替換它們的行爲。

就我個人而言,我喜歡爲我要模擬的類定義接口,然後模擬接口。這樣,我一定會避免這種問題。

+0

這聽起來像是答案。上面的語法對我來說看起來不錯... – jpoh 2009-07-08 09:07:03