Как очистить предыдущие ожидания от объекта?
Я хотел бы установить возвращаемое значение
_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 во втором вызове, я хочу переопределить первое ожидание.
Это упростит мой сценарий тестирования.
Ответы
Ответ 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
.