Сбросить ожидания на StrictMock - PullRequest
0 голосов
/ 05 марта 2020

У меня есть тестовый объект, который принимает фабрику, которая создает таймфреймы.

interface ITimeFrame
{
    Datetime BeginTime {get;}
    Datetime EndTimd {get;}
}

interface ITimeframeFactory
{
    ITimeFrame Create(DateTime beginTime, DateTime endTime);
}

class MyClass
{
    public MyClass(ITimeframeFactory timeframeFactory) {...}

    public void MyAction() {...}

    public void SetIntoPrecondition() {...}
}

Если мой тестовый объект находится в определенном предварительном условии, и я вызываю MyAction, я ожидаю, что таймфрейм вызывается с ожидаемыми значениями для начала и времени окончания. Этот вызов выполняется ровно один раз.

Код будет выглядеть примерно так:

myTestObject.SetIntoPrecondition();
myTestObject.MyAction();

При установке моего тестового объекта в предварительное условие, TimeframeFactory несколько раз предлагается создать Timeframe. В этом тесте я не хочу беспокоиться о SetIntoPreCondition.

[Test]
public void MyAction_IfInPrecondition_CreatesTimeFrame_UsingBeginTimeEndTime()
{
     MockRepository mockRepository = new MockRepository();
     ITimeframeFactory mockedTimeframeFactory = mockRepository.StrictMock<ITimeframeFactory>();

     MyClass testObject = new MyClass(mockedTimeframeFactory);

     // before starting the test I need to set the testObject into the precondition
     // this will create several Timeframes, which need to have proper values, because they will be
     // used in MyAction.

     using (mockRepository.Record())
     {
         // expect several requests to create a TimeFrame
         // (or stub if you like, does not change my problem)
         // while arranging I don't care about the parameters
         mockedTimeframeFactory.Expect((factory) => factory.Create(
               Arg<DateTime>.Is.Anything,
               Arg<DateTime>.Is.Anything))

         // when called, use the input parameters to create a mocked timeframe:
        .WhenCalled((call) =>
        {
            DateTime beginTime = (DateTime)call.Arguments[0];
            DateTime endTime = (DateTime)call.Arguments[1];

            ITimeframe mockedTimeframe = mockRepository.Stub<ITimeframe>();
            mockedTimeframe.Stub((timeframe) => timeframe.BeginTime).Return(beginTime);
            mockedTimeframe.Stub((timeframe) => timeframe.EndTime).Return(endTime);
            call.ReturnValue = mockedTimeframe;

            // set the mockedTimeframe from Record into Replay mode:
            mockedTimeframe.Replay();
        });
     }

Хорошо, запись закончена, теперь мы готовы поставить объект в предварительное условие:

using (mockRepository.Playback())
{
    testObject.SetIntoPrecondition(); 
}

В других тестах и с помощью отладчика я убедился, что это создало несколько таймфреймов. В этих тестах я смог получить доступ к свойствам созданных таймфреймов.

Теперь, когда мое устройство выполнено, я хочу проверить, что если я вызову MyAction, то таймфрейм будет запрошен для создания другого таймфрейма. На этот раз я ожидаю определенных параметров. Поэтому вместо Args<DateTime>.Is.Anything я хочу проверить значения.

В этом вопросе SO: Как очистить предыдущие ожидания Я прочитал, что должен использовать следующее:

mockRepository.BackToRecordAll() // which calls the other BackToRecordAll with options All
mockRepository.Replay();

Готов переопределить мои ожидания:

DateTime expectedBeginTime = ...
Datetime expectedEndTime = ...

using (mockRepository.Record())
{
    // expect several requests to create a TimeFrame
    // (or stub if you like, does not change my problem)
    // while arranging I don't care about the parameters
    mockedTimeframeFactory.Expect((factory) => factory.Create(
          Arg<DateTime>.Is.Equal(expectedBeginTime),
          Arg<DateTime>.Is.Equal(expectedEndTime))
          .WhenCalled((call) =>
          {
              DateTime beginTime = (DateTime)call.Arguments[0];
              DateTime endTime = (DateTime)call.Arguments[1];

              ITimeframe mockedTimeframe = mockRepository.Stub<ITimeframe>();
              mockedTimeframe.Stub((timeframe) => timeframe.BeginTime).Return(beginTime);
              mockedTimeframe.Stub((timeframe) => timeframe.EndTime).Return(endTime);
              call.ReturnValue = mockedTimeframe;

              // set the mockedTimeframe from Record into Replay mode:
              mockedTimeframe.Replay();
         });
     }

Готов действовать и утверждать:

using (mockRepository.Playback())
{
    testObject.MyAction();
}

Увы, я получаю исключение:

Система .InvalidOperationException: 'Method' ITimeframeFactory.Create (равно 1-1-2020 0:00:00, равно 12-12-2000 0:00:00); ' для возврата требуется возвращаемое значение или исключение. '

Так внезапно, когда WhenCalled больше не работает.

По сути, вопрос: если вам нужны ожидания (или заглушка ( )) чтобы ваш StrictMock подготовил ваш объект к тесту, а затем вы хотите изменить ожидания для выполнения теста, тогда, очевидно, BackToRecordAll и Replay недостаточно.

...