I'm writing unit tests using NUnit and Rhino Mocks to generate a stub. I'd like to use the .WhenCalled
method to control the return value of a stubbed method. It works as expected when I pass a lambda statement to the method, but not when I pass a method delegate.
For example, say I have the following interface:
public interface INumberCollection
{
int[] GetNumbers();
}
And for my test class I have the following:
[TestFixture]
public class MyTests
{
private INumberCollection _collection;
private Action<MethodInvocation> _action;
[OneTimeSetUp]
public void MyTests_OneTimeSetup()
{
_collection = MockRepository.GenerateStub<INumberCollection>();
_collection.Stub(c => c.GetNumbers())
.Repeat.Any()
.Return(new[] {0, 0, 0})
.WhenCalled(x => { x.ReturnValue = new[] {1, 2, 3}; });
}
[Test]
public void MyTest()
{
var result = _collection.GetNumbers();
Assert.That(result, Is.EqualTo(new[] {1, 2, 3}));
}
}
The test passes. However, the test fails when I replace the setup method with the following:
[OneTimeSetUp]
public void MyTests_OneTimeSetup()
{
_collection = MockRepository.GenerateStub<INumberCollection>();
_collection.Stub(c => c.GetNumbers())
.Repeat.Any()
.Return(new[] {0, 0, 0})
.WhenCalled(_action);
_action = x => { x.ReturnValue = new[] { 1, 2, 3 }; };
}
I expected .WhenCalled
to call the delegate stored in _action
and return {1, 2, 3}
, but instead it's returning {0, 0, 0}
, as if .WhenCalled
is being skipped completely. I even inserted a breakpoint inside the lambda and verified that it is never hit when debugging the test.
Why is _action
never getting called?
_action
isn't getting called because it is null
when it is passed to .WhenCalled
.
Because _action
is being passed to .WhenCalled
as a parameter, changing its value after it's been passed doesn't have any effect. To fix this, make the assignment before passing it to .WhenCalled
:
[OneTimeSetUp]
public void MyTests_OneTimeSetup()
{
_action = x => { x.ReturnValue = new[] { 1, 2, 3 }; };
_collection = MockRepository.GenerateStub<INumberCollection>();
_collection.Stub(c => c.GetNumbers())
.Repeat.Any()
.Return(new[] {0, 0, 0})
.WhenCalled(_action);
}