我想设置一个返回值
_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,我想覆盖第一个期望。
这有助于大大简化我的测试场景。
答案 0 :(得分:74)
有三种方式:
您可以使用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);
答案 1 :(得分:22)
对于这些情况,我创建了一个简单的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();
答案 2 :(得分:7)
为了社区的目的,我将添加此内容以添加到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
时都会执行lambda表达式,因为我们创建了一个引用returnValue
的闭包,它将始终查找{{1>的当前值}}