这是我的问题,我想模拟一个在初始化时创建线程并在销毁时关闭它的类.我的模拟类没有理由实际创建和关闭线程.但是,为了模拟一个类,我继承了它.当我创建mock类的新实例时,会调用基类构造函数,从而创建线程.当我的模拟对象被销毁时,将调用基类析构函数,尝试关闭该线程.
如何在不必处理实际资源的情况下模拟RAII类?
您改为创建一个描述类型的接口,并让真实类和模拟类继承该类型.所以如果你有:
class RAIIClass { public: RAIIClass(Foo* f); ~RAIIClass(); bool DoOperation(); private: ... };
你会做一个像这样的界面:
class MockableInterface { public: MockableInterface(Foo* f); virtual ~MockableInterface(); virtual bool DoOperation() = 0; };
从那里开始.
首先,你的课程可能很好地设计用于它们,但设计不合适用于测试,这不一定是不合理的.并非一切都很容易测试.
大概你想要使用另一个函数或类,它使用你想要模拟的类(否则解决方案是微不足道的).让我们称之为"用户",后者称为"Mocked".以下是一些可能性:
更改用户使用Mocked的抽象版本(您可以选择使用哪种抽象:继承,回调,模板等....).
为您的测试代码编译不同版本的Mocked(例如,在编译测试时#def out RAII代码).
让Mocked接受一个构造函数标志来关闭它的行为.我个人会避免这样做.
只需要花费分配资源的成本.
跳过测试.
如果你不能修改User或Mocked,最后两个可能是你唯一的办法.如果您可以修改用户,并且您认为将代码设计为可测试很重要,那么您应该先探索其他任何一个选项.请注意,在使代码具有通用性/灵活性和保持简单性之间存在折衷,这两者都是令人钦佩的品质.