假设您正在测试类A
并且它有dependency injection的B
,它的依赖注入为C
。
所以你模拟B
但它的唯一构造函数需要注入C
,所以你也必须模拟C
以及注入模拟的C
到嘲讽的B
,然后注入到A
?
如果您有5个连续依赖关系,该怎么办?使用依赖注入嘲笑C++类
有什么替代方案?
我使用Google Mock,所以具体答案也会有所帮助。
假设您正在测试类A
并且它有dependency injection的B
,它的依赖注入为C
。
所以你模拟B
但它的唯一构造函数需要注入C
,所以你也必须模拟C
以及注入模拟的C
到嘲讽的B
,然后注入到A
?
如果您有5个连续依赖关系,该怎么办?使用依赖注入嘲笑C++类
有什么替代方案?
我使用Google Mock,所以具体答案也会有所帮助。
在这种情况下,你应该通过指针注入,而不是通过引用,那么你可以传递一个NULL指针。假设你是一个对象确实是一个模拟对象而不是一个假对象,这将工作,因此它没有真正依赖注入的对象。
对于boost::shared_ptr
,你可以做到以下几点:
boost::shared_ptr<C> null_c_ptr;
MockB mock_b(null_c_ptr);
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;
}
在您的测试您创建不依赖于任何类。然后你只用B测试界面这样,你打破的一个模拟乙在C.创建不依赖下的模拟乙依赖是非常简单的:
class MockB : public B {
public:
MOCK_METHOD0(doSomething, void());
};
好,但繁琐的解决方案。如果可能的话,我宁愿让框架有一个自动化的宏...(在http://groups.google.com/group/googlemock/browse_thread/thread/2ed342a384456795上打开一个关于它的线程) – Jonathan 2011-04-25 11:38:11
感谢接受答案。我认为你想要的东西可能不可能用宏来做,因为它需要宏来解析C++源代码,因为没有可用的反射。 – mikelong 2011-04-25 11:58:10
您可能需要阅读googlemock cookbook上的界面:http://code.google.com/p/googlemock/wiki/CookBook#Alternative_to_Mocking_Concrete_Classes。 – User 2011-07-08 15:57:40
有趣,接受-2分:) – 2014-06-19 17:49:24