【问题标题】:How to (Google)Mock the DBUS interface?如何(谷歌)模拟 DBUS 接口?
【发布时间】:2012-12-06 21:36:03
【问题描述】:

假设我有一堂课,代码如下

void MessageBuilder::Init(DBusMessage* pMsg)
{
    if (NULL != m_pMsg)
    {
        ::dbus_message_unref(m_pMsg);
    }
    // m_pMsg is a private data member
    m_pMsg = pMsg;
    ::dbus_message_iter_init_append(m_pMsg, &m_objArgs);
}

DBUS 调用位于命名空间中,因此是 ::(我相信)。谁能建议如何模拟/存根 ::dbus_* 调用?

【问题讨论】:

    标签: unit-testing googlemock


    【解决方案1】:

    使用 GoogleMock,您可以伪造类的虚拟方法。但是 ::dbus_* 函数不是任何类的成员(您是对的,它们位于命名空间中:全局命名空间)。所以你不能(直接)使用 GoogleMock。

    James W. Grenning 在 Test-Driven Development for Embedded C 中为您的问题提出了一些解决方案:

    1. 链接时替换:不要将测试代码链接到包含 ::dbus_* 功能代码的原始库,而是在测试项目中创建新的 C/CPP 文件,这些文件实现了所有的伪造::dbus_* 被测试组件使用的函数。还将被测组件添加到测试项目中,因此链接器将自动解析 ::dbus_* 对您的假货的调用。
    2. 函数指针替换:不要直接使用被测组件中的 ::dbus_* 函数,而是使用函数指针,这些函数指针在生产代码中初始化为 ::dbus_* 函数,在测试代码中初始化为假函数。
    3. 预处理器替换:使用#define 覆盖名称,例如#define dbus_message_unref(p) fake_dbus_message_unref(p) 让被测组件调用你自己的假函数fake_dbus_message_unref()。这种方法需要将被测组件添加到测试项目中。

    如果提案 1. 可行并且不会产生链接问题,那么它比提案 2 的工作量要少得多。提案 3. 的俗气部分是它实际上更改了(!)被测组件的代码,所以我宁愿回避3。建议1.是推荐的方式。

    另一种选择是在 ::dbus_* 函数周围使用带有虚拟方法的 C++ 包装类,因此您可以使用像 GoogleMock 这样的模拟工具来伪造它们。编写这样的包装器可能意味着相当多的努力。作为捷径,您可以搜索 DBUS C++ 包装库——如果幸运的话,您会找到一个可模拟的。

    【讨论】:

    • 我正在为 dbus* 库函数编写一个包装类,并将模拟它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-27
    • 1970-01-01
    • 1970-01-01
    • 2018-06-11
    • 2010-10-31
    • 2012-11-13
    • 1970-01-01
    相关资源
    最近更新 更多