使用gtest将所有方法声明为virtual以进行mocking
Declare all methods virtual for mocking using gtest?
目前我正试图在我的C++项目中使用Google Mock框架(gtest)实现一些基本的Mock。然而,这个框架并不能很好地处理非虚拟方法,这需要一些(至少IMHO)丑陋的解决方案(使用模板)。当然,一个简单的解决方案是简单地使每个方法都是虚拟的,但该框架建议不要这样做,这也不是我真正喜欢的解决方案。
所以,我开始思考,难道没有一种方法可以在不更改实际源文件的情况下,为测试声明每个方法都是虚拟的吗?这可以是一个传递给编译器的标志,也可以是一些CPP voodoo。如果这确实是可能的,那么这种解决方案的缺点是什么?
模拟非虚拟函数的任何其他方式(最好使用gtest/gmock)也值得赞赏。
如果相关的话,我现在正在使用GCC和X-Code。
只有两种方法可以获得虚拟函数:
-
将其声明为虚拟
-
(从具有相同名称、相同签名、虚拟函数的基类继承)
第一个可以显式完成,也可以通过宏完成,但这会导致代码难看。第二个可以使用模板库来完成,它通常默认为空,但为了测试目的,您可以使用一个类来实例化它,该类镜像您的接口,但声明函数为虚拟的。
struct Empty { };
template <class BaseT = Empty>
class YourClass : public BaseT {
public:
void foo();
};
有争议但足以表明意图。您可以使用上面的代码进行普通的、非虚拟的使用。然后,对于您的测试:
struct YourClassTester {
virtual void foo() = 0;
virtual ~YourClassBase() { }
};
YourClass<YourClassTester> testable;
等等。当然,这确实意味着你测试的代码与实际使用的代码不同,而且可能存在可检测的差异,例如:
类大小较大(vtbl)
存储器布局不同的
RTTI支持在测试中有效,在生产中无效
根据原始类别(is_standard_layout、is_pod、is_trivialy_copyable等),一些类型特征的结果也可能不同
如果这些都无关紧要,并且您不介意将类作为模板,那么您可以尝试这种方法。
相关文章:
- C++核心准则 C35 对于接口类"A base class destructor should be either public and virtual, or protected and nonv
- 当我从下面的代码中删除关键字 virtual 时,它可以正常工作,否则会出现错误。在这里"virtual"字的意义是什么?
- 在基类中调用的 VIrtual 基函数,C++
- C++类:virtual和override,或者两者都没有
- g++ [[noreturn]] on a virtual method
- "virtual"对C++析构函数有何影响?
- 多重继承:跳过'virtual'关键字并拒绝菱形层次结构的使用?
- 错误"pure virtual method called",当此方法已被覆盖时
- 为什么C++尝试/捕获没有捕获"pure virtual call"异常?
- 防止 CRTP 特征码在"pure virtual"调用中堆栈溢出
- Protobuf 生成的C++类无法针对 iOS 进行编译,并显示错误"Only virtual member functions can be marked 'final'"
- 为什么必须将"virtual"放入基类中,而不是仅在子类中使用"override"?在C++
- 使用 -march 编译会导致线程说"pure virtual method called"
- "Prototype pattern"和"Virtual constructor"是相同的模式吗?
- 为什么Virtual继承2类会增加对象大小
- 在C 11或更高版本中,是否可以通过Lambda来实现单方法纯Virtual C 接口
- C++ "virtual"关键字放置
- 在C++中声明一个类"final : public virtual"有用吗?
- C++ "Pure Virtual Function Being Called"失败
- 使用gtest将所有方法声明为virtual以进行mocking