How to clear previous expectations on an object?
There are three ways:
You can reset the expectations by using BackToRecord
I have to admit that I never really used it because it is awkward.
// clear expectations, an enum defines which
_stubRepository.BackToRecord(BackToRecordOptions.All);
// go to replay again.
_stubRepository.Replay();
Edit: Now I use it sometimes, it is actually the cleanest way. There should be an extension method (like Stub) which does it - I think it just got forgotten. I would suggest to write your own.
You can use Repeat.Any()
It 'breaks' the order of the stubbed definition and "overrides" previous definitions. But it's somehow implicit. I use it sometimes because it is easy to write.
_stubRepository.Stub(x => x.Contains(null))
.IgnoreArguments()
.Return(false)
.Repeat.Any();
You can create a new mock
Trivial, but explicit and easy to understand. It is only a problem if you want to keep plenty of definitions and only change one call.
_stubRepository = MockRepository.GenerateMock<IRepository>();
_stubRepository.Stub(x => x.Contains(null))
.IgnoreArguments()
.Return(false);
For these situations, I created a simple RinoMocks extention method to better show the intent of the stub and promote readability.
public static void OverridePrevious<T>(this IMethodOptions<T> options)
{
options.Repeat.Any();
}
So instead of a cryptic call like the following that may require a comment:
[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
}
You can get a more readable test that better shows the intent of the .Repeat.Any() calls:
carStub.Stub(x => x.Model).Return(null).OverridePrevious();
For the sake of the community I'll add this to add to Stefan's list of options above:
If the return value needs to be changed frequently I find it clean and efficient to use a closure as follows.
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;
The lambda expression will be executed every time Contains
is called and because we created a closure referencing returnValue
, it will always look up the current value of returnValue
.