我正在尝试找出模拟单例对象的最佳/首选方法。
我这里有一个单例课程。
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();
}
有一个Foo类在某个时候调用单例...
#include <Foo.h>
#include <Singleton.h>
void Foo::action(int value) {
if (value > 1) {
Singleton::getInstance()->flush();
} else {
// do nothing
}
}
我想模拟Singleton对象,使其具有以下FooTest来确保调用flush方法。
TEST_F(FooTest, testFlushIsCalled) {
auto foo = Foo();
foo.someAction(2);
EXPECT_CALL(Singleton::getInstance(), flush()).Times(1);
}
提前谢谢!
答案 0 :(得分:2)
单件非常很难模拟(并且通常很难进行单元测试)。
如果您可以将单例调用替换为依赖注入,则可以减轻很多麻烦,并且可以使用标准方法来模拟它,即
Foo::Foo(Singleton* flushSingleton) : myFlushSingletion(flushSingleton) {};
void Foo::action(int value) {
if (value > 1) {
myFlushSingletion->flush();
} else {
// do nothing
}
}
无法使用更深的魔法-但后果自负...
您可以将(本地静态)Singleton实例转换为受保护的静态变量(及其虚拟函数)
class Singleton {
//...
protected:
static std::shared_ptr<Singleton> mySingletonInstance;
//...
}
然后,您可以派生一个MockSingleton,将其放置在实际Singleton的mySingletonInstance
中-但是正如我所说的...更好地重构代码,以后您会更快乐。