我的代码如下:
class B;
class A
{
A()
{
}
bool MethodA()
{
B *pB = new B();
bool bRet = pB->SomeFunction();
// remaining logic;
return bRet;
}
~A(){}
};
我需要为 MethodA 编写测试。所以我认为我需要打破对 B 类的依赖。最好的方法是什么?如果它是一个成员变量,我可以通过构造函数注入一个存根。是否存在不涉及更改生产代码的解决方案? 如果需要改变,最好的方法是什么?
我使用NUnit并在这里处理一些非托管代码。请帮忙!
编辑:我错过了另一个头疼的问题! B类是一个C ++类,我不应该改变它的实现。 A类在C ++ / CLI中,它充当B的包装器。所以我认为这会抑制B接口的概率,因为我无法触及B.
答案 0 :(得分:2)
没有。没有解决方案不包括改变设计,主要是因为该设计不好。 A和它的依赖关系B是紧密耦合的,这使得它在面向对象编程方面变得很糟糕:你需要反转依赖关系的控制。测试只是设计糟糕的一个原因,但它并不是唯一的原因。可移植性,灵活性,关注点分离等等。
使其可测试并使其更好的最佳方式(唯一的好方法)是依赖注入。
您需要使用构造函数(将B接口作为参数)或setter将B注入A中。控制A(并且new A()
)的任何人都应该将依赖关系B传递给它(new A(new B())
或A.setB(new B())
)。
一旦完成,对方法进行单元测试将变得非常容易。
答案 1 :(得分:1)
如果不做出改变,你就无法做到这一点,但你可以这样做:
class A
{
A()
{
}
A(B *b)
{
pB = b;
}
B *pB;
bool MethodA()
{
if (*pB == null) {
*pB = new B();
}
bool bRet = pB->SomeFunction();
// remaining logic;
return bRet;
}
~A(){}
};
至少在C#这是我认为你写的。没有处理很多指针,所以我不确定我的语法是否合适,但基本上我的想法是对pB进行延迟初始化,以便在你想要的时候注入依赖但不会破坏当前的行为。您可以获得更多的动力并为A
internal制作备用构造函数,然后使用InternalsVisibleTo
属性仅将其显示给您的测试类。