Question

Say I have a class with the following code

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);
}

The DBUS calls are in a namespace, hence the :: (I believe). Can anyone suggest how to mock/stub out the ::dbus_* calls?

Was it helpful?

Solution

With GoogleMock you can fake virtual methods of classes. But the ::dbus_* functions are not member of any class (you are right, they are in a namespace: the global namespace). So you cannot use GoogleMock (directly).

James W. Grenning in Test-Driven Development for Embedded C suggests some solutions to your problem:

  1. Link-time substitution: don't link the test code against the original library containing the ::dbus_* function code, but instead create new C/CPP files in the test project, which implement fakes of all ::dbus_* functions used by the component under test. Also add the component under test to the test project, so the linker will automatically resolve ::dbus_* calls to your fakes.
  2. Function pointer substitution: instead of using directly the ::dbus_* functions in your component under test use function pointers, which are initialized to ::dbus_* functions in production code and fake functions in test code.
  3. Preprocessor substitution: use #define to override names, e.g. #define dbus_message_unref(p) fake_dbus_message_unref(p) to make the component under test call your own fake function fake_dbus_message_unref(). This approach requires to add the component under test to the test project.

If proposal 1. is feasible and does not create link problems, it is much less work than proposal 2. The cheesy part of proposal 3. is that it actually changes (!) the code of the component under test, so I would rather shy away from 3. Proposal 1. is the recommended way.

Another alternative could be to use C++ wrapper classes with virtual methods around the ::dbus_* functions, so you can use a mocking tool like GoogleMock to fake them. Writing such wrappers would probably mean quite some effort. As short cut you could search for a DBUS C++ wrapper library -- if you are lucky you find a mockable one.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top