单元测试中的C ++和依赖注入

时间:2010-04-09 18:04:12

标签: c++ unit-testing dependency-injection

假设我有一个像这样的C ++类:

class A
{
    public:
        A()
        {

        }

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

    private:
        B m_B;
}

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

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

我想你可以证明通过使用接口来重构A会更容易。但是有些情况下两个类可能需要紧密耦合吗?

3 个答案:

答案 0 :(得分:9)

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

答案 1 :(得分:2)

如果B确实是注入A的依赖项,那么您应该考虑其他一些选项。首先是在施工时注入B

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

    private:
        const B& m_B;
};

如果您确实想在B对象的生命周期内修改A,请问自己是否真的是B的所有者。如果没有,传递一个指针,并假设传递它的人负责其生命周期 - 这是一个棘手的路线,可能需要你使用ref-counting指针。

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

答案 2 :(得分:0)

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