I'm writing a unit test against an MVC Controller that has a dependency on IFoo
. Foo
(the implementation) has one method I'd like to stub, but I want to leave the other intact. How can I set this up using RhinoMock
?
Foo
has several dependencies that I'd prefer not to mock to save writing additional lines of code and cluttering my test.
public interface IFoo{
int Method1();
int Method2();
}
public class Foo : IFoo{
//lot's of dependencies
public Foo(IBar bar, IBaz baz, IStackOverflow so){}
}
[Test]
public void What_I_Have_So_Far(){
//arrange
//load the real IFoo from Ninject (DI)
var mockFoo = new Ninject.Kernel(new MyExampleModule())
.Get<IFoo>();
//I want this test to use the real Method1, but not Method2
//so stub Method2
mockFoo
.Stub(x => x.Method2()) //<---- blows up here
.Returns(42);
//act
var controllerUnderTest = new Controller(mockFoo);
Using this approach, RhinoMock throws an Exception:
System.InvalidOperationException : The object 'MyApplication.MyExampleModule' is not a mocked object.
How can I stub method2
?
I know I could create IFoo
as a mock via MockRepository.GenerateMock
, but then'd I'd have to copy the real implementation of Method1
.
Both Brad and Jimmy's solution seam to work equally well, I picked Brad's only because it was less code to write.
However, after researching this a bit further, it looks like what I need is an AutoMocker. There seams to be one for StructureMap and Moq, but not RhinoMocks: https://github.com/RhinoMocks/RhinoMocks/issues/3
You have to do it the other way around. Create mocked IFoo
and redirect some calls to real IFoo
(this has to be done via WhenCalled
extension):
var realFoo = new Ninject.Kernel(new MyExampleModule()).Get<IFoo>();
var mockFoo = MockRepository.GenerateStub<IFoo>();
mockFoo.Stub(f => f.Method2()).Return(42);
mockFoo.Stub(f => f.Method1())
.WhenCalled(invocation =>
{
invocation.ReturnValue = realFoo.Method2();
})
.Return(whateverValue);
The final Return
is required even though we override it few lines before. Otherwise Rhino will throw exception.