0

假设我们有以下类AB

class A
{
    virtual void Init() { DoSomething(); }
};

class B : public A
{
    virtual void Init() { DoSomethingSpecial(); A::Init(); }
};

在我们的单元测试中,我们只想测试B,即使用Hippomocks进行测试,调用B::Init()实际上会调用DoSomethingSpecial()

B* b_p = new B();
m_mockRepository_p->ExpectCall(b_p, DoSomethingSpecial);
b_p->Init();

现在我们不想期待所有来自A's 的调用,Init()所以我们想编写如下内容:

m_mockRepository_p->ExpectCall(b_p, A::Init);

最后一个期望会导致一个未处理的异常,我认为这是可以的,因为我们正在将我们正在调用的方法与我们想要期望的基本版本混合在一起。投射b_p到 anA没有帮助。

该特定用例有什么解决方案吗?

4

1 回答 1

0

......这是一个有趣的。我认为没有办法解决这个问题。对 A::Init 的调用不是通过虚函数表完成的(正如您明确知道要调用哪一个),因此它属于您无法模拟的非虚函数。

添加它的一个复杂因素是,如果您在 B 上获取 A::Init 的地址,您仍然会得到 vtable 指针,因此如果您愿意,您甚至无法替换该函数(例如,使用 C 函数模拟逻辑)。

我只能推荐通用重构解决方案来解决这个问题 - 使 A 和 B 独立类,使 B 包含 A(私有继承)或从 A 和 B 中提取接口并将 B 变成装饰器。最后一个听起来最好,但这取决于A和B实际上是什么......

于 2014-01-19T22:25:16.390 回答