Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Simple Mocking in C++

DZone's Guide to

Simple Mocking in C++

· DevOps Zone ·
Free Resource

Learn more about how CareerBuilder was able to resolve customer issues 5x faster by using Scalyr, the fastest log management tool on the market. 

I’ve been working in C++ for a few months now – after three years we’ve been apart.
I always amazes me how simple things I took for granted do not exist (at least not out of the box) in C++, one of which are reflection.

Two weeks ago I needed to make sure that a method was called in a test, I could have used Google’s mocking framework but I needed simpler and quicker solution. I just wanted to know in a specific point at the test if a method was called.

Although C++ does not have reflection it does have macros (i.e. #Define) and I’ve utilized the C++ macros to create the following class:

#ifndef __TESTLISTENERBASE_H__
#define __TESTLISTENERBASE_H__
 
#include <unordered_set>
#include <string>
 
class TestListenerBase
{
protected:
    void AddMethodCall(std::string methodName)
    {
        _methodsCalled.insert(methodName);
    }
 
    bool WasCalled(std::string methodName)
    {
        return _methodsCalled.count(methodName) > 0;
    }
private:
    std::unordered_set<std::string> _methodsCalled;
};
 
#define REGISTER_METHOD(METHODNAME) \
    void METHODNAME () override\
    { \
        AddMethodCall(#METHODNAME); \
    } \
    bool METHODNAME##WasCalled() \
    { \
        return WasCalled(#METHODNAME); \
    } 
 
#endif

By inheriting from the class above I could define the “mocked” methods, each method would have another method  auto-generated so I can test if the method was called.

#ifndef __MY_CLASS_MOCK__
#define __MY_CLASS_MOCK__
 
#include "TestListenerBase.h"
#include "MyClass.h"
 
class MyClassMock : public MyClass, public TestListenerBase
{
public:
    REGISTER_METHOD(DoSomething);
};
 
#endif

Using this solution I needed to declare each method, the good news is that renaming the method would cause the mocked method name to change as well.

Using the new "mock object" is a simple as writing code:

#include "stdafx.h"
#include <memory>
#include "MyClassMock.h"
 
int _tmain(int argc, _TCHAR* argv[])
{
    MyClassMock mock;
 
    bool result = mock.DoSomethingWasCalled(); // return false
 
    mock.DoSomething();
 
    result = mock.DoSomethingWasCalled(); // result true
 
    return 0;
}

That’s it – it’s not perfect but it works.

In case you like parameters in your method you’ll have to improve this example – it’s not hard and I know you’re up to the task.

Happy coding…



Find out more about how Scalyr built a proprietary database that does not use text indexing for their log management tool.

Topics:

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}