开发者

Mocking, virtual and more

This question would have been asked many times w.r.t to RhinoMocks, but I will try to present a little differently. I have a situation like this below -

class A
{
   X parentOfB;
   A()
   { 
       X parentOfB = someObj;
       if(<something>)
       {
         B objB = parentOfB as B  // NOTE THIS 
         if(objB.Foo)            // call the property here
         {
            // some code ....
         }
       }
   }
}

class B : X
{
   // gets initialised to true somewhere in the program. Don't bother much
   protected bool status ;
   B() {}

   // Property
   public bool Foo
   {
     return status;
   }

}

Mocking: Now, I want to do something like this -

var mock = new MockRepository();

var myObjB = mock.StrictMock<B>();

// call Db class to populate the objB object and then set the expectation as 
// below  
// ...
// ...
Expect.Call(myObjB.Foo).Return(true);
mock.ReplayAll();
var objA = new A();
mock.VerifyAll();

Error: Invalid call, the last call has been used or no call has been made (make sure that you are calling a v开发者_开发知识库irtual (C#) / Overridable (VB) method).

Problem is that, the concrete class B is being accessed in ctor of A for accessing the Property. How do I handle this scenario in RhinoMocks ? If I make the propeerty Foo as virtual, it works fine. But, I do not want to do that.


First, check your exception stack trace, and see where the "invalid call" error is coming from. Does it come from the Expect.Call line? If so, remove the A class from the picture.

Second, all mocking frameworks need a way to check if a property/method has been called. They replace the regular property/method code with some code that records how the call happened. In order to replace code, a mocked property or method must be virtual or abstract, or the mock should be created for an interface.


If a property needs to be mocked, and its original behaviour can't be mocked away, here's one alternative. You move the code from B.Foo into a new property, and create a virtual dummy replacement for B.Foo.

class B
{
    // Old code here
    public bool RealFoo { get { return status; } }

    // New dummy code
    public virtual bool Foo { get { return RealFoo; } }
}

Then from your mocking code, you can record when Foo gets called, and you can call the "real" code too:

var myObjB = mock.StrictMock<B>();

Expect.Call(myObjB.Foo).Return(myObjB.RealFoo);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜