2

I want to do the following...

Until a method has been called a certain property must always return value x After a method has been called a certain property must always return value y

I am familiar with the WhenCalled method in RhinoMocks, which allows me to set that return value after the method has been called, but I cannot think of a way to set the return value before the call. So far I have the following code...

counter.Expect(n => n.IncreaseCounter())
   .WhenCalled(i => counter.Expect(n => n.GetCounter)
   .Return(Y).Repeat.Any());

Is this possible?

ΩmegaMan
  • 29,542
  • 12
  • 100
  • 122
Mark Pearl
  • 7,573
  • 10
  • 47
  • 57

3 Answers3

4

There are 2 solutions to do the trick:

  1. With usage WhenCalled():

    var counter = MockRepository.GenerateStub<ICounter>();
    
    int cnt = 1;
    
    counter
        .Stub(c => c.GetCounter)
        .Return(0)
        .WhenCalled(invocation => { invocation.ReturnValue = cnt; });
    
    counter
        .Stub(c => c.IncreaseCounter())
        .WhenCalled(invocation => { ++cnt; });
    
  2. With usage Do() handler

    var counter = MockRepository.GenerateStub<ICounter>();
    
    int cnt = 1;
    
    counter
        .Stub(c => c.GetCounter)
        .Do((Func<int>)(() => cnt));
    
    counter
        .Stub(c => c.IncreaseCounter())
        .Do((Action)(() => ++cnt));
    

The idea is the same in both cases: Initially GetCounter returns 1. Each IncreaseConter() call increases value which is returned by GetCounter.

PS
If you are not going to do assertions against counter then it is probably suitable to setup it with Stub() rather than with Expect(). See e.g. this question for details.

Community
  • 1
  • 1
Alexander Stepaniuk
  • 6,217
  • 4
  • 31
  • 48
1

Just setup new return value for property in a callback of mocked method:

Mock<IFoo> fooMock = new Mock<IFoo>();
fooMock.Setup(foo => foo.Property).Returns(1);
fooMock.Setup(foo => foo.Method())
       .Callback(() => fooMock.Setup(x => x.Property).Returns(42));

Mocked property will return 1 until mocked method will be called. Then its return value will be set to 42. All further calls to mocked property will return 42.

Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
0

Based on Alexander's solution... the following was what I was looking for...

var counter = MockRepository.GenerateStub<ICounter>();

int x = 1;
int y = 2;
int cnt = x;

counter
    .Stub(c => c.GetCounter)
    .Return(0)
    .WhenCalled(invocation =>
    {
        invocation.ReturnValue = cnt;
        cnt = y;
    });
Mark Pearl
  • 7,573
  • 10
  • 47
  • 57