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!!
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With