假设我有一个像这样的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会更容易。但是有些情况下两个类可能需要紧密耦合吗?
答案 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的引用传递给其他可以工作且需要最少代码更改的内容。