Reputation: 1703
I've started to work with Rhino recently and encountered a very unexpected behavior that I couldn't overcome.
The issue is that I have an infrastructure of my stubs and in one of my tests I needed to change one of the predefined stubs (in my infrastructure) to return a different value then the default one.
I've reproduce the issue in the following code:
[TestFixture]
public class UnitTest1
{
private IWorker _worker;
[SetUp]
void Setup()
{
_worker = MockRepository.GenerateStub<IWorker>();
_worker.Stub(w=>w.DoWork()).Return(0);
}
[Test]
public void DoWork_StubbingFunctionTwice_CallingTheLastStub()
{
int expected = 1;
_worker.Stub(w => w.DoWork()).Return(expected);
int actual =_worker.DoWork();
Assert.AreEqual(expected, actual);
}
}
public interface IWorker
{
int DoWork();
}
someone knows why the Rhino stubs are behaving this way and more important how can I solve it in the cleanest way?
Upvotes: 5
Views: 1651
Reputation: 8725
When you specify a behavior on a fake object in RhinoMocks
without any constraint(RepeatOnce and etc..) the behavior will stay and you won't be able to override it.(actually option 1 shows how you can...)
In your case you specify a specific behavior in the Setup
method:
_worker.Stub(w=>w.DoWork()).Return(0);
The above line will execute before _worker.Stub(w => w.DoWork()).Return(expected);
.
The best practice for SetUp
/ TestInitialize
attributes is to group inside them only settings which you want to apply in all test methods.
By default any method with a return value returns the default(T)
so you can remove _worker.Stub(w=>w.DoWork()).Return(0);
and then any thing will work.
If your real case is more complex:
Option1: clear the mock
// clear expectations, an enum defines which
_worker.BackToRecord(BackToRecordOptions.All);
// go to replay again.
_worker.Replay();
Option2: limit the behavior
_worker.Stub(w=>w.DoWork()).Return(0).Repeat.Once(); // or the max time you need...
and then add a loop inside the test method:
for(...; i < num of time; ...)
_worker.DoWork();
Option3: create a new fake and CUT(class under test)
Upvotes: 4