Как очистить предыдущие ожидания на объекте? - PullRequest
60 голосов
/ 21 апреля 2009

Я хотел бы установить возвращаемое значение

_stubRepository.Stub(Contains(null)).IgnoreArguments().Return(true);

но затем в конкретном тесте переопределите это ожидание, чтобы вернуть false.

Что-то вроде:

_stubRepository.ClearExpectations();  //<- this does not exist, I'm just making something up
_stubRepository.Stub(Contains(null)).IgnoreArguments().Return(false);

Обратите внимание, я не хочу, чтобы ожидание возвращало false при втором вызове, я хочу переопределить первое ожидание.

Это поможет значительно упростить мой сценарий тестирования.

Ответы [ 3 ]

75 голосов
/ 21 апреля 2009

Есть три способа:

Вы можете сбросить ожидания, используя BackToRecord

Я должен признать, что никогда не использовал его, потому что это неловко.

// clear expectations, an enum defines which
_stubRepository.BackToRecord(BackToRecordOptions.All);
// go to replay again.
_stubRepository.Replay();

Редактировать: Теперь я использую его иногда, это на самом деле самый чистый способ. Должен быть метод расширения (например, Stub), который делает это - я думаю, что он просто забыт. Я бы предложил написать свой.

Вы можете использовать Repeat.Any ()

Он «нарушает» порядок определения-заглушки и «переопределяет» предыдущие определения. Но это как-то неявно. Я использую это иногда, потому что это легко написать.

_stubRepository.Stub(x => x.Contains(null))
  .IgnoreArguments()
  .Return(false)
  .Repeat.Any();

Вы можете создать новый макет

Тривиально, но явно и легко понять. Это проблема, только если вы хотите сохранить множество определений и изменить только один вызов.

_stubRepository = MockRepository.GenerateMock<IRepository>();
_stubRepository.Stub(x => x.Contains(null))
  .IgnoreArguments()
  .Return(false);
22 голосов
/ 02 июля 2012

Для этих ситуаций я создал простой метод расширения RinoMocks, чтобы лучше показать назначение заглушки и повысить читабельность.

public static void OverridePrevious<T>(this IMethodOptions<T> options)
{
    options.Repeat.Any();
}

Поэтому вместо загадочного вызова, подобного следующему, который может потребовать комментарий:

[SetUp]
public void Setup()
{
    carStub.Stub(x => x.Model).Return("Model1");
    carStub.Stub(x => x.Model).Return("Model2");
}

[Test]
public void SomeTest()
{
    //Arrange
    //overrides previous stubs that were setup for the Model property
    carStub.Stub(x => x.Model).Return(null).Repeat.Any();

    //Act
    //Assert
}

Вы можете получить более читаемый тест, который лучше показывает цель вызовов .Repeat.Any ():

carStub.Stub(x => x.Model).Return(null).OverridePrevious();
7 голосов
/ 11 июля 2014

Ради сообщества я добавлю это, чтобы добавить в список вариантов Стефана выше:

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

bool returnValue = true;
_stubRepository.Stub(x => x.Contains(null)).IgnoreArguments().Do(new Func<bool>(() => {
    return returnValue;
}));

returnValue = false;
// Calls to Contains now return false;

returnValue = true;
// Calls to Contains now return true;

Лямбда-выражение будет выполняться каждый раз, когда вызывается Contains, и поскольку мы создали замыкание, ссылающееся на returnValue, оно всегда будет искать значение current returnValue.

...