【问题标题】:Google Test Framework: is better to use shadowing or virtual methods?谷歌测试框架:使用阴影或虚拟方法更好?
【发布时间】:2016-07-28 10:37:59
【问题描述】:

在下面的示例中,我想对class A 进行单元测试,以验证当A::request 被调用时,B::response() 也被调用:

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( );
...

问题是:如何“注入”MockB 来替代B m_b

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

第二个技巧

  • 制作B::responsevirtual
  • B m_b 更改为std::unique_ptr<B> m_b
  • 在测试设置期间将 m_b 值替换为 class MockB 的实例

第二种方法意味着更多的代码更改,我不确定它的优点。

【问题讨论】:

    标签: c++ unit-testing testing googletest googlemock


    【解决方案1】:

    解决问题的正确方法是第二种技术。更一般地说,很难将单元测试代码“改造”到设计时没有考虑到它的组件上——您几乎总是需要对正在测试的代码进行重大修改。

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

    【讨论】:

    • 所以你基本上是在建议一种测试驱动的设计方法。模板技术非常有趣。顺便说一句,这将对代码产生巨大影响(很多代码要移动到头文件和内联文件中)。
    • 是的,我非常喜欢测试驱动设计的许多方面,尽管我并不虔诚地遵循它。我认为即使你没有为甚至在编写实现之前可能发生的每一个小场景都创建一个单元测试(TDD 会鼓吹你应该这样做),你仍然会发现添加测试作为事后的想法非常困难,一些严肃的代码重新设计 - 你无法摆脱它,测试是侵入性的。就我个人而言,我喜欢将我写的几乎所有东西都模板化,这样我就可以应用 Mock 模板参数
    猜你喜欢
    • 2011-06-14
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    • 2010-10-24
    • 1970-01-01
    • 2012-05-02
    相关资源
    最近更新 更多