How to clear previous expectations on an object?

前端 未结 3 1161
囚心锁ツ
囚心锁ツ 2020-11-29 02:37

I would like to set up a return value

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

but then in a specific test, ove

相关标签:
3条回答
  • 2020-11-29 03:07

    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.

    0 讨论(0)
  • 2020-11-29 03:26

    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();
    
    0 讨论(0)
  • 2020-11-29 03:29

    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);
    
    0 讨论(0)
提交回复
热议问题