首先 - 最好的方法是重新设计您的 SUT 类,以通过某些抽象接口注入 D。因为我在下面描述的解决方法确实很棘手 - 所以将来不太容易维护和理解......
如果您要在 UT 目标中伪造 D 类的实现 - 那么您可以为 D 制作 Mock 类:DMock
. This DMock
不会与D
- 不是从它派生 - 但它需要与真/假 D 对象配对。
所以 - 请看示例:
创建 DMock - 模仿 D 接口(请注意,您应该仅模拟公共函数 - 因为您的 SUT 仅使用公共函数):
class DMock
{
public:
MOCK_METHOD0(pubMethod1, void ());
MOCK_METHOD0(pubMethod2, int ());
};
将真实的(但假的)D 对象与 DMock 对象配对 - 如下所示:
class DMockRepo
{
public:
// for UT
void addMockToUse(DMock* dMock) { freeMock.push_back(dMock); }
// for implementing D fake methods
DMock& getMock(D* original)
{
// TODO: use more sophisticated way to add mock to map...
if (not usedMock[original])
{
usedMock[original] = freeMock.front();
freeMock.pop_front();
}
return *useddMock[original];
}
static DMockRepo& getInstance() { return instance; } //singleton
private:
DMockRepo() {} // private
static DMockRepo instance;
std::map<D*,DMock*> usedMock;
std::deque<DMock*> freeMock;
};
使用模拟创建 D 类公共方法的假实现:
void D::pubMethod1()
{
DMockRepo::getInstance().getMock(this).pubMethod1();
}
//
非公开方法是无关紧要的 - 所以做你喜欢做的事......
并使用 DMockRepo 设置 D 对象的期望:
TEST(Usage,Example)
{
DMock dMock;
DMockRepo::getInstance().addMockToUse(&dMock);
SUT sut; // you should know how many D objects SUT needs - I assume just one
EXPECT_CALL(dMock, pubMethod1());
sut.doSomethingThatCallsDpubMethod1();
}