模拟、虚拟等
这个问题可能已经被问过很多次了 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先,检查异常堆栈跟踪,并查看“无效调用”错误来自何处。它来自
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 theA
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.
如果需要模拟某个属性,并且无法模拟其原始行为,那么这里有一种选择。您将代码从
B.Foo
移至新属性,并为B.Foo
创建虚拟虚拟替换。然后,从您的模拟代码中,您可以记录
Foo
何时被调用,并且您也可以调用“真实”代码: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 forB.Foo
.Then from your mocking code, you can record when
Foo
gets called, and you can call the "real" code too: