How to clear previous expectations on an object?

.NetRhino Mocks

.Net Problem Overview


I would like to set up a return value

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

but then in a specific test, override that expectation to return false.

Something like:

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

Notice, I do not want the expectation to return false on the second call, I want to override the first expectation.

This would help simplify my testing scenario greatly.

.Net Solutions


Solution 1 - .Net

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);

Solution 2 - .Net

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();

Solution 3 - .Net

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGeorge MauerView Question on Stackoverflow
Solution 1 - .NetStefan SteineggerView Answer on Stackoverflow
Solution 2 - .NetMoMoView Answer on Stackoverflow
Solution 3 - .NetMicah HahnView Answer on Stackoverflow