Dependency injection 模拟C++;具有依赖项注入的类

Dependency injection 模拟C++;具有依赖项注入的类,dependency-injection,mocking,googlemock,Dependency Injection,Mocking,Googlemock,假设您正在测试类A,它有一个B的类,该类的依赖项注入为C,因此您模拟了B,但它唯一的构造函数需要注入C,那么,您是否也必须模拟C,并将模拟的C注入模拟的B中,然后才将其注入A?如果您有5个连续的依赖项呢 有哪些替代方案 我使用,所以一个具体的答案也会有帮助。如果您更改设计,使类依赖于接口而不是具体的类,那么您就摆脱了构造函数问题。除了提高可测试性外,它还可以提高可重用性和可维护性,代价是增加代码(接口)。Emile的想法是正确的,您应该依赖接口而不是具体的类。因此,在您的示例中,它将类似于: #

假设您正在测试类
A
,它有一个
B
的类,该类的依赖项注入为
C

,因此您模拟了
B
,但它唯一的构造函数需要注入
C
,那么,您是否也必须模拟
C
,并将模拟的
C
注入模拟的
B
中,然后才将其注入
A

如果您有5个连续的依赖项呢

有哪些替代方案


我使用,所以一个具体的答案也会有帮助。

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

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;
}

在这种情况下,应该通过指针而不是引用进行注入,然后可以传递空指针。假设您的对象确实是一个模拟对象,而不是一个伪对象,那么这将起作用,因此它对注入的对象没有真正的依赖关系

对于
boost::shared_ptr
,您可以执行以下操作:

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

您能详细说明一下吗?这会消除依赖项注入的必要性吗?它不会消除依赖项注入,只会注入一个接口。因此,编译时只有接口必须在范围内。这减少了耦合,并且(在你的例子中)C不再出现,因为你不再是一个具体的B。很好但很麻烦的解决方案。如果可能的话,我更愿意让框架有一个宏来自动化这个过程。。。(在这里打开了一个帖子)谢谢你接受了答案。我认为您想要的是宏的不可能,因为它需要宏解析C++源,因为没有可用的反射。您可能想从GooGeMoLooCopyBooin上读取这些信息:
boost::shared_ptr<C> null_c_ptr;
MockB mock_b(null_c_ptr);