GoogleTest Mock C ++单例

时间:2018-08-08 23:49:03

标签: c++ unit-testing googletest googlemock

我正在尝试找出模拟单例对象的最佳/首选方法。

我这里有一个单例课程。

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);
}

提前谢谢!

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中-但是正如我所说的...更好地重构代码,以后您会更快乐。