我有一个继承自另一个类的类,如下所述:
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()实现 - 如何在这种情况下调用Mocked版本的MockA :: Show()?
==================== UPDATE ========================== =======
下面的实现对我来说很有用:
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类所需的方法
答案 0 :(得分:0)
首先关闭:
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
覆盖原始实现。
答案 1 :(得分:0)
你必须使Show()虚拟以获得MockA :: Show()而不是A :: Show()。
答案 2 :(得分:0)
下面的实现对我来说很有用:
class A
{
public:
virtual void Show(){}
};
class B : public A
public:
void BMethod1(){Show()}
};
class BMock : public B
{
public:
MOCK_METHOD0(Show, void());
};
现在将BMock对象用于测试用例
答案 3 :(得分:0)
您可以使用Isolator++创建测试而无需设置:
<select ng-if="question.MasterDataCategoryId != null" id="{{question.QuestionId}}" ng-model="question.MasterData" ng-init="question.MasterData = questionnaireDataEditDefault" class="form-control" style="width: 200px; white-space:pre-wrap;">
<option selected="selected"></option>
<option ng-repeat="answer in answerData[question.MasterDataCategoryId]" value="{{answer.MasterData}}">{{answer.MasterData}}</option>
</select>