我有一个从另一类继承的类,如下所述:
class A
{
public:
virtual void Show(){}
};
class B : public A
public:
void BMethod1(){Show()}
};
现在我正在编写B类的测试用例 - 所以我嘲笑A类:
class MockA : public A
{
MOCK_METHOD0(Show, void());
};
以下是我的Google测试框架测试案例:
TEST(BTEST , ShowMethod)
{
B bobj;
MockA aobj;
EXPECT_CALL(aobj , Show());
bobj.BMethod1(); // updated as from bobj.METHOD0()
}
但是测试用例正在调用实际a :: show()实现 - 在这种情况下如何调用overed :: show()的模拟版本?
=========================================================================
下面的实现为我带来了技巧:
class A
{
public:
virtual void Show(){}
};
class B : public A
public:
void BMethod1(){Show()}
};
class BMock : public B
{
public:
MOCK_METHOD0(Show, void());
};
现在使用bmock对象测试您的B类所需方法
您必须使Show()Virtual才能获得Mocka :: show()而不是a :: show()。
首先:
bobj.METHOD0();
是完全错误的。METHOD0
不是访问模拟功能的有效符号。
您要测试的是B::BMethod1()
调用A::Show()
,对吗?
因此,将该行更改为
bobj.BMethod1();
您可以更改B
类以将其基类实现作为模板参数:
class A
{
public:
virtual void Show(){}
// ^^^^^^^ See note 1
};
template<class Base>
class B : public Base
public:
void BMethod1(){Show()}
};
然后您使用
B<A> bobj;
bobj.BMethod1();
在您的生产代码中,
B<MockA> bobj;
EXPECT_CALL(bobj , Show());
bobj.BMethod1(); // <<< trigger the expectation
在您的单元测试代码中。
作为侧节点:
这是一个众所周知的模式,可以通过模板类型参数注入基类,称为 mixin 。
虽然 mixins 主要是为了提供接口的分段实现,这些实现主要是为了构成公共接口实现。
但是,在试图单位测试有关这些举止的课程时,遇到这种情况,如果我在那里有一个设计缺陷,则会自动引导我解决这个问题:
B
确实是A
,还是将A
的实例用作拥有或引用的成员变量?
如果我想在单位测试中进行测试,我会考虑将B
类重构为
class B {
A& a_;
public:
B(A& a) a_(a) {}
void BMethod1() { a_.Show(); }
};
并相应地调整测试方案:
TEST(BTEST , ShowMethod)
{
MockA aobj;
B bobj(aobj);
EXPECT_CALL(aobj , Show());
bobj.BMethod1();
}
至于您的评论
目的是测试案例可以返回模拟的值-Expect_call(mmocka,show()).willonce(return(false));
这应该与上面的示例一起使用:
EXPECT_CALL(bobj, Show()) .WillOnce(Return(false));
,但要求 Show()
称为
virtual bool Show();
在A
类中,喜欢
MOCK_METHOD0(Show, bool());
在MockA
类中。
1) virtual
声明是必要的,以允许MockA
覆盖原始实现。
下面的实现对我有用:
class A
{
public:
virtual void Show(){}
};
class B : public A
public:
void BMethod1(){Show()}
};
class BMock : public B
{
public:
MOCK_METHOD0(Show, void());
};
现在,将BMOCK对象用于测试用例
您可以使用隔离器 创建测试而无需设置:
class A
{
public:
void Show() {}
};
class B : public A
{
public:
void BMethod1() { Show(); }
};
TEST(BTEST, ShowMethod)
{
B bobj;
auto aobj = FAKE<A>();
bobj.BMethod1();
ASSERT_WAS_CALLED(aobj->Show());
}