你如何模拟在c ++中使用RAII的类

Gor*_*son 9 c++ unit-testing mocking

这是我的问题,我想模拟一个在初始化时创建线程并在销毁时关闭它的类.我的模拟类没有理由实际创建和关闭线程.但是,为了模拟一个类,我继承了它.当我创建mock类的新实例时,会调用基类构造函数,从而创建线程.当我的模拟对象被销毁时,将调用基类析构函数,尝试关闭该线程.

如何在不必处理实际资源的情况下模拟RAII类?

haz*_*zen 12

您改为创建一个描述类型的接口,并让真实类和模拟类继承该类型.所以如果你有:

class RAIIClass {
 public:
  RAIIClass(Foo* f);
  ~RAIIClass();
  bool DoOperation();

 private:
  ...
};
Run Code Online (Sandbox Code Playgroud)

你会做一个像这样的界面:

class MockableInterface {
 public:
  MockableInterface(Foo* f);
  virtual ~MockableInterface();
  virtual bool DoOperation() = 0;
};
Run Code Online (Sandbox Code Playgroud)

从那里开始.


ejg*_*ttl 6

首先,你的课程可能很好地设计用于它们,但设计不合适用于测试,这不一定是不合理的.并非一切都很容易测试.

大概你想要使用另一个函数或类,它使用你想要模拟的类(否则解决方案是微不足道的).让我们称之为"用户",后者称为"Mocked".以下是一些可能性:

  1. 更改用户使用Mocked的抽象版本(您可以选择使用哪种抽象:继承,回调,模板等....).
  2. 为您的测试代码编译不同版本的Mocked(例如,在编译测试时#def out RAII代码).
  3. 让Mocked接受一个构造函数标志来关闭它的行为.我个人会避免这样做.
  4. 只需要花费分配资源的成本.
  5. 跳过测试.

如果你不能修改User或Mocked,最后两个可能是你唯一的办法.如果您可以修改用户,并且您认为将代码设计为可测试很重要,那么您应该先探索其他任何一个选项.请注意,在使代码具有通用性/灵活性和保持简单性之间存在折衷,这两者都是令人钦佩的品质.