2011-09-21 119 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。 –