聚合对象使用 googlemock 调用的模拟函数

Mock function called by aggregate object using googlemock

我有一个场景,其中实例化本地对象以调用该 class 的方法,即 setSessionId()。 setSessionId的定义如下:

int Cli::setSessionId()
{
    SessionHandler oHandleSession;
    return oHandleSession.getSessionId(sSessionId);
}

现在为了模拟 SessionHandler 的函数,我使用宏在我想要模拟的函数之前添加 virtual 关键字,在这种情况下 getSessionId()as this class 不是抽象的,函数也不是纯虚拟的。(我知道 Hi-Perf Dependency Injection 但现阶段不想进入)

如果是这样的话

int Cli::setSessionId(SessionHandler* oHandleSession)
{
  ...
  return oHandleSession->getSessionId(sSessionId);
}

将模拟对象传递给函数会很简单 setSessionid() 但由于使用了聚合,我该如何模拟此函数 getSessionId()?

可以使用静态多态,也可以使用link-时间替换。

对于静态多态性,你可以这样做:

class DefaultSessionHandler {
  // methods implemented as you do now
};

template <typename T>
class SessionHandlerT {
  // methods implemented in terms of delegation to methods on T
};

using SessionHandler = SessionHandlerT<DefaultSessionHandler>; 

这可能有点麻烦,并且会引入额外的编译时间,虽然它可以工作,但我不太喜欢这种方法,尽管我之前已经做过多次。

使用 link 时间替换,您提供 SessionHandler 的替代实施并在 link 时间解决问题。这意味着您有 SessionHandler class 的一些其他实现,即使它具有相同的名称,它也会做一些不同的事情。同样,这很麻烦,但可以解决。

这两种方法都有各自的问题和痛苦。一种更好的单元测试方法是通过重构 SUT 来简单地使用依赖注入。

另一种方法是放弃单元测试,只进行集成测试。这也有它自己的一系列问题。