我无法解决这个问题:我有一个名为MyClass的类,该类具有MyUsedClass类型的私有成员。为了创建单元测试,我有一个MyUsedClass的模拟(模拟)版本。我想用模拟的MyUsedClass私有成员或MyUsedClass的真正私有成员动态调用MyClass。因为我想动态地调用它,所以无法使用#defines和#ifdefs。
基本上我想做这样的事情:
class MyClass {
public:
MyClass(bool mock = false) {}; // Default bool to false.
~MyClass(void) {};
void DoSomething(void) { /* Do something with MyUsedObject here... */ };
void DoMore(void);
...
private:
if (mock) {
MyUsedClassMock MyUsedObject;
} else {
MyUsedClassReal MyUsedObject;
}
};
MyClass MyObject; // Create default instance with real MyUsedObject.
MyClass MyObject(true); // Create instance with the mock MyUsedObject.
但是这当然不起作用,因为如果类定义中的if语句无法执行。
另一种方法是使用多态性并创建基类,真实类和模拟类。基类将具有所有功能的所有实现,并且通过选择调用MyClass的真实版本或模拟版本,我可以选择MyUsedObject的类型。
class MyClassBase {
public:
MyClassBase(void) {};
~MyClassBase(void) {};
void DoSomething(void) { /* Do something with MyUsedObject here... */ };
void DoMore(void);
...
private:
// No MyUsedObject in the Base class.
};
class MyClassReal : public MyClassBase {
public:
MyClassReal(void) {};
~MyClassReal(void) {};
private:
MyUsedClassReal MyUsedObject; // Here is MyUsedObject created, but then "Real".
};
class MyClassMock : public MyClassBase {
public:
MyClassMock(void) {};
~MyClassMock(void) {};
private:
MyUsedClassMock MyUsedObject; // Here is MyUsedObject created, but then "Mock".
};
MyClassReal MyObject; // Create instance with the real MyUsedObject.
MyClassMock MyObject; // Create instance with the mock MyUsedObject.
不幸的是,这也行不通,因为MyClassBase函数实现对MyUsedObject尚不了解,所以我在这里遇到错误。一种想法是用来在基类中创建虚拟MyUsedObject,但是这里的问题是基类尚不知道对象的类型(真实或模拟)。此外,数据声明中不允许使用“虚拟”,因此无论如何尝试再次获得更多错误。
我在这里想念什么?
答案 0 :(得分:1)
多态方法是必经之路。但是,您必须提出不同的建议:
class MyUsedClass { }; // the base class, having (pure?) virtual functions
class MyUsedClassReal : public MyUsedClass { }; // provides real functionality
class MyUsedClassMock : public MyUsedClass { }; // mocks the functionality
派生类将提供实际场景和模拟时特别需要的实现。您自己的类现在将动态地使用一个或另一个:
class MyClass
{
public:
MyClass(bool mock = false)
~MyClass(void) {};
void doSomething();
private:
std::unique_ptr<MyUsedClass> myUsedObject;
};
MyClass::MyClass(bool mock)
: myUsedObject(mock ? new MyUsedClassMock() : new MyUsedClassReal())
{ }
void MyClass::doSomething() { /* use the pointer! */ };
如果您遵循StoryTeller的提示(“依赖注入”),则会将对象作为参数传递给构造函数,而不是在内部创建它,这可能是更可取的:
MyClass::MyClass(std::unique_ptr<MyUsedClass> object)
: myUsedObject(std::move(object))
{ }
也有一个std::unique_ptr
作为参数,很明显MyClass
将获得所提供对象的所有权(是它的接收器);这适用于您的示例,而不是“总是执行”规则,它取决于用例,在其他情况下,共享指针(成员和参数)可能更合适。