Изменение ожиданий от насмешек носорога за один вызов метода - PullRequest
2 голосов
/ 21 сентября 2011

У меня есть DispatcherTimer, и я проверяю статус занят / свободен компонента в отметке таймера этого таймера. Мне нужно подождать, пока компонент освободится, что-то вроде метода IsBusy () вернет false, а затем я должен автоматически что-то запустить. Я хочу протестировать сценарий, сначала имитируя занятость компонента, а затем через некоторое время освободить его и увидеть, что автоматическая функция запускается. Конечно, как только я вызываю тестируемый код, я вхожу в ожидание. Можно ли установить новые ожидания от теста и отправить обновление производственного кода, чтобы я мог делать то, что мне нужно? Я использую Nunit для модульных тестов.

Ответы [ 2 ]

1 голос
/ 21 сентября 2011

Вы можете использовать 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 (я просто произвольно решил подождать 10 секунд).

ClassUnderTest.MethodUnderTest() должен вызывать MyComponent.IsBusy() в какой-то момент его реализации либо прямо, либо, возможно, косвенно, через обработчик событий Tick DispatcherTimer, который вы упомянули. Не видя ваш код, я думаю, что у вас может быть что-то похожее на это:

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 голосов
/ 21 сентября 2011

Ваши ожидания могут создаваться динамически, но они должны быть настроены в одном месте, а не «интерактивно». Вы не должны пытаться изменить их, когда выполняете тестируемый код.

Чтобы достичь своей цели, вы можете попробовать использовать опцию Repeat, чтобы проверять цикл несколько раз:

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

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