模拟、虚拟等

发布于 2024-12-05 10:27:31 字数 1151 浏览 0 评论 0原文

这个问题可能已经被问过很多次了 RhinoMocks,但我会尝试以不同的方式呈现。我有这样的情况 -

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;
   }

}

嘲笑: 现在,我想做这样的事情 -

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();

错误: 无效调用,已使用最后一次调用或未进行任何调用(确保您正在调用虚拟 (C#)/可重写 (VB) 方法)。

问题是,在 A 的构造函数中访问具体类 B 来访问属性。如何在 RhinoMocks 中处理这种情况?如果我将 Foo 属性设为虚拟,它就可以正常工作。但是,我不想那样做。

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 virtual (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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

找个人就嫁了吧 2024-12-12 10:27:31

首先,检查异常堆栈跟踪,并查看“无效调用”错误来自何处。它来自 Expect.Call 行吗?如果是这样,请从图片中删除 A 类。

其次,所有模拟框架都需要一种方法来检查属性/方法是否已被调用。他们用一些记录调用如何发生的代码替换常规属性/方法代码。为了替换代码,模拟的属性或方法必须是虚拟的或抽象的,或者应该为接口创建模拟。

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.

二智少女 2024-12-12 10:27:31

如果需要模拟某个属性,并且无法模拟其原始行为,那么这里有一种选择。您将代码从 B.Foo 移至新属性,并为 B.Foo 创建虚拟虚拟替换。

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

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

然后,从您的模拟代码中,您可以记录 Foo 何时被调用,并且您也可以调用“真实”代码:

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

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

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文