Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GoogleTest Mock C++ singleton

I am trying to find out the best/preferred way of mocking a singleton object.

I have a class Singleton here.

class Singleton {

public:

static std::shared_ptr<Singleton> getInstance() {
    static std::shared_ptr<Singleton> instance =
            std::make_shared<Singleton>(); // Guaranteed to be destroyed.
    // Instantiated on first use.
    return instance;
}

Singleton(Singleton const&) = delete;
Singleton(Singleton &&) = delete;
Singleton& operator=(Singleton const&) = delete;
Singleton& operator=(Singleton &&) = delete;
~Singleton();

void flush();

}

with a Foo class calling the singleton at some point...

#include <Foo.h>
#include <Singleton.h>

void Foo::action(int value) {

    if (value > 1) {
        Singleton::getInstance()->flush();
    } else {
        // do nothing
    }
}

I would like to mock the Singleton object have the follow FooTest to make sure the flush method is called.

TEST_F(FooTest, testFlushIsCalled) {
    auto foo = Foo();
    foo.someAction(2);
    EXPECT_CALL(Singleton::getInstance(), flush()).Times(1);
}

Thanks in advance!!

like image 211
Dillon Avatar asked Nov 02 '25 15:11

Dillon


1 Answers

Singletons are very troublesome to mock (and a pain in unit testing in general).

If you can replace the singleton call with dependency injection you will relieve lots of pain and can use standard methods to mock it, i.e.

Foo::Foo(Singleton* flushSingleton) : myFlushSingletion(flushSingleton) {};

void Foo::action(int value) {
    if (value > 1) {
        myFlushSingletion->flush();
    } else {
        // do nothing
    }
}

Failing that you may be able to use darker magic - but do so at your own peril...
You might turn the (local static) Singleton instance into a protected static variable (and its functions virtual)

class Singleton {
//...
protected:
static std::shared_ptr<Singleton> mySingletonInstance;
//...
}

Then you can derive a MockSingleton which places itself in the mySingletonInstance of the real Singleton - but as I said... better refactor your code, you will be happier in the future.

like image 115
CharonX Avatar answered Nov 04 '25 06:11

CharonX



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!