2016-07-28 16 views
0

在下面的例子中,我想单元测试class A以验证当A::request被调用时,B::response()称为以及:Google测试框架:最好使用阴影还是虚拟方法?

class A 
{ 
public: 
    void request() 
    { 
     m_b.response(); 
    } 

private: 
    B m_b; 
}; 

class B 
{ 
public: 
    void response(); 
}; 

为了做到这一点,class B必须被嘲笑:

class MockB : public B 
{ 
public: 
    MOCK_METHOD0(response, void()); 
}; 

,以便测试将包含:

class TestA : public A 
{ 
    ... 
}; 

... 
EXPECT_CALL(m_b, response()).Times(1); 
request(); 
... 

这个问题我s:如何“注入”MockB作为B m_b的替代品?

首先tecnique: 创建ShadowB类重定向方法调用class MockB。这要求原始代码位于外部二进制文件中,但不需要对实际代码进行任何更改。

二tecnique

  • 制作B::responsevirtual
  • 更改B m_bstd::unique_ptr<B> m_b
  • 测试设置

第二种方法MEA期间的class MockB实例替换m_b值ns更多的代码更改,我不知道它的亲。

回答

1

解决您的问题的正确方法是第二种技术。更一般地说,将单​​元测试代码“复制”到非设计的组件上非常困难 - 您几乎总是需要对正在测试的代码进行重大修改。

使用虚拟函数替代模拟回调对象来代替真实回调对象,都从一个通用接口继承是一种非常普遍的方法。另一种选择是让你的类被测试为模板类,并用Mock对象替换它们的模板参数。

+0

所以你基本上是建议一个测试驱动的设计方法。非常有趣的模板技术。顺便说一句,这会对代码产生巨大的影响(很多代码要移动到标题和内联文件中)。 – nyarlathotep108

+0

是的,我非常喜欢测试驱动设计的许多方面,尽管我没有虔诚地遵循它。我认为即使你没有为编写实现之前可能发生的每一个小场景创建一个单元测试(TDD会鼓吹你应该这样做),但你仍然会发现添加测试相当困难,一些严重的代码重新设计 - 你无法摆脱它,测试是侵入性的。我个人喜欢模板几乎所有我写的,所以我可以应用模拟模板参数 – Smeeheey

相关问题