Подтвердить что ты не робот

Как очистить предыдущие ожидания от объекта?

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

_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 во втором вызове, я хочу переопределить первое ожидание.

Это упростит мой сценарий тестирования.

4b9b3361

Ответ 1

Существует три способа:

Вы можете reset ожидать, используя 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);

Ответ 2

В этих ситуациях я создал простой способ расширения 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();

Ответ 3

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

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

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, оно всегда будет искать текущее значение returnValue.