2010-04-09 228 views
5

假设我有一个C++类,像这样:C++和依赖注入单元测试

class A 
{ 
    public: 
     A() 
     { 

     } 

     void SetNewB(const B& _b) { m_B = _b; } 

    private: 
     B m_B; 
} 

为了单元测试这样的事情,我将不得不打破B. A的依赖。由于A类持有到一个实际的对象而不是一个指针,我将不得不重构这段代码来获取一个指针。此外,我需要为B创建一个父接口类,以便在测试SetNewB时可以传入我自己的B的假。

在这种情况下,不使用依赖注入进行单元测试会使现有代码进一步复杂化?如果我让B成为一个指针,我现在介绍堆分配,现在有一段代码负责清理它(除非我使用ref计数指针)。另外,如果B是一个相当平凡的类,只有一些成员变量和函数,为什么要为它引入一个全新的接口,而不是仅仅使用B的实例进行测试?

我想你可能会认为使用接口重构A更容易。但是有些情况下可能需要紧密耦合两个类?

回答

8

我想你对单元测试的想法太过分了。在这种情况下,A和B是一个单位,即A没有B就不能存在。首先,测试B并确保它通过了所有B特定的单元测试,然后一旦通过,测试A并确保它表现它应该如何。

+0

有趣的是,我想我是在想象单元测试需要所有类彼此完全分离。但正如你所指出的,A绝对需要B来工作;所以他们实际上是一个单位。 – lhumongous 2010-04-09 18:22:54

0

根据你如何使用B,你可以使用std :: auto_ptr而不是ref-counting指针。只要您不需要将对B的引用传递给可以工作并需要最少代码更改的其他内容即可。

2

如果B真的是注入到A的依赖项,那么你应该考虑一些其他选项。首先是在建设时注入B

class A 
{ 
    public: 
     A(const B& _b) : m_B(_b) {} 

    private: 
     const B& m_B; 
}; 

如果你真的想你A对象的生命周期过程中修改B,然后问自己,如果你真的的B所有者。如果没有,传递一个指针,并假设通过它的人负责其生命周期 - 尽管这是一条棘手的路线,并且可能需要您使用ref-counts指针。

如果你想要做的是为自己拿一份B的副本,那么你可以在B上定义clone()方法。如果要使用B中包含的信息创建自己的对象,则可以在构造函数中注入MyBFactory,并将其与B一起使用。