c++mockingsingletongooglemockprivate-constructor

Mocking a class having private Constructor using GMOCK


I have a Singleton class with private Ctor, Dtor and one getInstance() method.

class Single {
public:
virtual void* alloc(size_t size, uint line){}
Single* getInstance() {
if(!m_Instance)
        m_Instance = __OSAL_NEW OSAL_Memory;
    return m_Instance;
}
private:
Single();
~Single();
static Single* m_Instance;
};


#define Allocate(size_t size)\
(Single::getInstance())->alloc(size, __LINE__)

I need to Mock this class using GMOCK. Is there any way around to mock it.


Solution

  • You could use factory pattern to create your object.

    #include <iostream>
    #include <functional>
    
    struct A
    {
        virtual ~A(){}
    
        virtual void foo() = 0;
    };
    
    struct Areal : A
    {
        virtual void foo(){
            std::cout<<"real"<<std::endl;
        }
    };
    
    struct Amock : A
    {
        virtual void foo(){
            std::cout<<"mock"<<std::endl;
        }
    };
    
    struct Single
    {
        typedef std::function< A*() > CreatorFn;
    
        static A* getInstance(){
            if ( ! instance() )
                instance() = (create())();
            return instance();
        }
    
        static void setCreator( CreatorFn newFn ){
            create() = newFn;
        }
    
    private:
    
        static CreatorFn& create(){
            static CreatorFn f( [](){return new Areal;} );
            return f;
        }
        static A*& instance(){
            static A* p=nullptr;
            return p;
        }
    };
    
    
    bool useMock = true;
    
    int main()
    {
        if ( useMock )
        {
            Single::CreatorFn mockFn( [](){ return new Amock; } );
            Single::setCreator( mockFn );
        }
    
        Single::getInstance()->foo();
    }
    

    You just have to make sure that you set the creator before accessing the instance. Otherwise, a default creator function is going to be invoked.