假设您正在测试类A
,它有一个依赖注入,B
其中的依赖注入为C
.
所以你模拟B
但它唯一的构造函数需要注入C
,所以你是否也必须模拟C
并将模拟注入C
模拟B
然后才将其注入A
?
如果您有 5 个连续的受抚养人怎么办?
有哪些替代方案?
我使用Google Mock,所以一个具体的答案也会有所帮助。
假设您正在测试类A
,它有一个依赖注入,B
其中的依赖注入为C
.
所以你模拟B
但它唯一的构造函数需要注入C
,所以你是否也必须模拟C
并将模拟注入C
模拟B
然后才将其注入A
?
如果您有 5 个连续的受抚养人怎么办?
有哪些替代方案?
我使用Google Mock,所以一个具体的答案也会有所帮助。
Emile 的想法是正确的,你应该依赖接口而不是具体的类。因此,在您的示例中,它将类似于:
#include <iostream>
using namespace std;
class C {
public:
int x;
};
class B {
public:
~B(){};
virtual void doSomething() = 0;
};
class ConcreteB : public B{
public:
ConcreteB(C c) : m_c(c) {}
void doSomething(){
std::cout << "HelloWorld" << std::endl;
}
private:
C m_c;
};
class A{
public:
A(B *b): m_b(b){}
void functionToTestWithSideEffect(){
m_b->doSomething();
}
private:
B *m_b;
};
//#include <gmock/gmock.h>
int main() {
C c;
c.x = 42;
ConcreteB b(c);
A a(&b);
a.functionToTestWithSideEffect();
return 0;
}
在您的测试中,您创建了一个不依赖于任何类 C 的模拟 B。然后您只使用 B 测试接口。通过这种方式,您打破了 A 对 C 的依赖。创建一个不依赖于 C 的模拟 B 很漂亮简单的:
class MockB : public B {
public:
MOCK_METHOD0(doSomething, void());
};
如果你改变设计使类依赖于接口而不是具体类,你就摆脱了构造函数的问题。除了提高可测试性外,它还可以提高可重用性和可维护性,但代价是更多的代码(接口)。
在这种情况下,您应该通过指针而不是通过引用进行注入,然后您可以传递一个 NULL 指针。假设您的对象确实是模拟对象而不是假对象,这将起作用,因此它对注入的对象没有真正的依赖关系。
因为boost::shared_ptr
您可以执行以下操作:
boost::shared_ptr<C> null_c_ptr;
MockB mock_b(null_c_ptr);