2011-04-20 61 views
2

假设您正在测试类A并且它有dependency injectionB,它的依赖注入为C
所以你模拟B但它的唯一构造函数需要注入C,所以你也必须模拟C以及注入模拟的C到嘲讽的B,然后注入到A
如果您有5个连续依赖关系,该怎么办?使用依赖注入嘲笑C++类

有什么替代方案?

我使用Google Mock,所以具体答案也会有所帮助。

回答

-2

在这种情况下,你应该通过指针注入,而不是通过引用,那么你可以传递一个NULL指针。假设你是一个对象确实是一个模拟对象而不是一个假对象,这将工作,因此它没有真正依赖注入的对象。

对于boost::shared_ptr,你可以做到以下几点:

boost::shared_ptr<C> null_c_ptr; 
MockB mock_b(null_c_ptr); 
+3

有趣,接受-2分:) – 2014-06-19 17:49:24

4

如果您更改设计以使类取决于接口而不是具体类,则可以摆脱构造函数问题。除了提高可测试性之外,它还可以提高可重用性和可维护性,代价是更多的代码(接口)。

+0

你能不能解释一下?这会消除依赖注入的必要性吗? – Jonathan 2011-04-20 08:08:16

+0

它不会删除依赖注入,只会注入一个接口。所以编译时只有接口必须在范围内。这减少了耦合,并且(在你的例子中)C不再可见,因为你不再具体的B了。 – Emile 2011-07-08 18:20:36

6

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()); 
}; 
+0

好,但繁琐的解决方案。如果可能的话,我宁愿让框架有一个自动化的宏...(在http://groups.google.com/group/googlemock/browse_thread/thread/2ed342a384456795上打开一个关于它的线程) – Jonathan 2011-04-25 11:38:11

+0

感谢接受答案。我认为你想要的东西可能不可能用宏来做,因为它需要宏来解析C++源代码,因为没有可用的反射。 – mikelong 2011-04-25 11:58:10

+0

您可能需要阅读googlemock cookbook上的界面:http://code.google.com/p/googlemock/wiki/CookBook#Alternative_to_Mocking_Concrete_Classes。 – User 2011-07-08 15:57:40