在单个方法调用中改变对犀牛模拟的期望

时间:2011-09-21 06:59:47

标签: c# .net rhino-mocks

我有一个DispatcherTimer,我在这个计时器的计时器滴答中检查组件的忙/闲状态。我必须等到组件空闲,像IsBusy()方法返回false,然后我必须自动启动一些东西。我想通过首先模拟要忙的组件来测试场景,然后在一段时间后将其释放并看到自动功能启动。当然,一旦我调用了测试代码,我就进入等待状态。是否有可能从测试中设定新的期望并将更新发送到生产代码,以便我可以做我需要做的事情?我正在使用Nunit进行单元测试。

2 个答案:

答案 0 :(得分:1)

您可以使用Rhino Mocks'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测试不同的睡眠时间(我只是随意选择等待10秒)。

ClassUnderTest.MethodUnderTest()应该在其实施的某个时刻直接或间接通过您提到的DispatcherTimerMyComponent.IsBusy()事件处理程序调用{​​{1}}。没有看到你的代码,我的猜测是你可能有类似的东西:

Tick

答案 1 :(得分:0)

您的期望可以动态创建,但应该在一个地方设置,而不是“交互式”。在锻炼你的代码时,你不应该试着改变它们。

要实现目标,您可以尝试使用Repeat选项允许检查循环一定次数:

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

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