2011-09-21 75 views
2

我有一個DispatcherTimer,我檢查該定時器的計時器滴答中組件的忙/閒狀態。我必須等到組件變得空閒,像IsBusy()方法返回false,然後我必須自動啓動一些東西。我想通過首先模擬組件忙於測試場景,然後在一段時間後讓組件自由並看到自動功能啓動。當然,一旦我調用被測代碼,我就進入等待狀態。是否有可能從測試中設定新的期望併發送更新到生產代碼,以便我可以做我需要做的事情?我正在使用Nunit進行單元測試。通過單一方法調用對犀牛嘲笑的期望

回答

1

可以使用犀牛嘲笑Do() Handler模擬預先指定的等待時間在組件的IsBusy()方法的嘲笑:

[TestFixture] 
public class TestClass 
{ 
    [Test] 
    public void MyTest() 
    { 
     var mocks = new MockRepository(); 
     var mockComponent = mocks.DynamicMock<MyComponent>(); 

     using (mocks.Record()) 
     { 
      Expect.Call(() => mockComponent.IsBusy()) 
       .Do((Func<bool>)(() => 
         { 
          System.Threading.Thread.Sleep(10000); // wait 10 seconds 
          return false; 
         })); 
      // perhaps define other expectations or asserts here... 
     } 

     using (mocks.Playback()) 
     { 
      var classUnderTest = new ClassUnderTest(mockComponent); 
      classUnderTest.MethodUnderTest(); 
     } 

     mocks.VerifyAll(); 
    } 
} 

然後,可以測試不同的睡眠時間經由多個單元測試根據需要或使用NUnit's Parameterized Tests(I只是任意選擇了等待10秒)。

ClassUnderTest.MethodUnderTest()應在其執行某些點直接或間接也許通過你所提到的DispatcherTimerTick事件處理程序調用MyComponent.IsBusy()。沒有看到你的代碼,我的猜測是,你可能有一些與此類似:

public class ClassUnderTest 
{ 
    private MyComponent myComponent; 

    public ClassUnderTest(MyComponent myComponent) 
    { 
     this.myComponent = myComponent; 
    } 

    public void MethodUnderTest() 
    { 
     dispatcherTimer = new System.Windows.Threading.DispatcherTimer(); 
     dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick); 
     dispatcherTimer.Interval = new TimeSpan(0,0,1); 
     dispatcherTimer.Start(); 
     // ... 
    } 

    private void dispatcherTimer_Tick(object sender, EventArgs e) 
    { 
     if(!myComponent.IsBusy()) 
     { 
      // do something else now... 
     } 
    } 
} 

public class MyComponent 
{ 
    public virtual bool IsBusy() 
    { 
     // some implementation that will be faked via the Do Handler 
     return false; 
    } 
} 
0

您的期望可以動態創建,但應該設置在一個地方,而不是「交互式」。在執行代碼測試過程中,您不應該嘗試更改它們。

爲了實現你的目標,你可以嘗試使用Repeat選項允許檢查,以循環一定次數:

mock.Expect(theMock => theMock.IsBusy()) 
    .Return(true) 
    .Repeat.Times(5); 

mock.Expect(theMock => theMock.IsBusy()) 
    .Return(false); 
+0

我沒有得到機會使用Rhino.Mocks非常頻繁,所以請糾正我,如果我錯了:)希望這個例子仍然適用,tho。 –