我有一个Java类,它有一个私有方法来计算一些默认值;和两个构造函数,其中一个省略了该值,并使用私有方法获取默认值。
public class C {
private static HelperABC getDefaultABC() {
return something; // this is a very complicated code
}
public C() {
return C(getDefaultABC());
}
public C(HelperABC abc) {
_abc = abc;
}
}
现在,我正在尝试为这个类编写测试,并且想测试BOTH构造函数;第二个构造函数传递默认值。
现在,如果getDefaultABC()
是公开的,那将是微不足道的:
// We are inside class test_C
// Assume that test_obj_C() method correctly tests the object of class C
C obj1 = new C();
test_obj_C(obj1);
HelperABC abc = C.getDefaultABC();
C obj2 = new C(abc);
test_obj_C(obj2);
但是,因为getDefaultABC()
是私有的,我无法从测试类中调用它 !!!。
所以,我被迫写了一些愚蠢的东西:
// Assume that test_obj_C() method correctly tests the object of class C
C obj1 = new C();
test_obj_C(obj1);
// here we will insert 20 lines of code
// that are fully copied and pasted from C.getDefaultABC()
// - and if we ever change that method, the test breaks.
// In the end we end up with "HelperABC abc" variable
C obj2 = new C(abc);
test_obj_C(obj2);
有没有办法解决这个难题(理想情况下,通过某种方式将C.getDefaultABC()
标记为除了类test_C之外的所有人除外)除了简单地将方法从私有更改为公共?
答案 0 :(得分:4)
There's no equivalent to friend in Java. (that link from T I above)我这样做的方法是将方法声明为包保护,如下所示:
static HelperABC getDefaultABC()
这样做,只要测试类与getDefaultABC()
位于同一个包中,就允许测试代码调用C
。当然,这会让同一个包中的任何其他类都调用它,但我认为你将不得不忍受这一点,这是你不用反射就可以做到的最好的。但是如果你使用反射,那么每个其他类也可以使用反射来调用getDefaultABC()
,因此它几乎就像“易受攻击”一样。我只是让它受到包保护,所以至少它比使用反射更具可读性。
我会告诉你怀疑的好处,并说你可能继承了这段代码,目前还不能测试。您需要做的就是让getDefaultABC()
进入可测试状态。测试甚至不一定要好,你只需要一些信心。一旦你对测试有了信心,你会发现getDefaultABC()
中的代码与获取默认ABC无关。较低级别的抽象,如连接到数据库或其他任何东西。您需要识别该代码并将其提取到自己的类中。然后,为提取的类编写更好的测试。
如果您将此代码重构为非常干净的状态,您应该能够摆脱不良测试并将getDefaultABC()
恢复到private
状态。 private
意味着内部实施。您不应该直接测试内部实现。
答案 1 :(得分:2)
不是绝对干净,但您可以使用反射在测试中调用私有方法 对我而言,使用反射似乎更好,因为它是非侵入性的,您不必仅仅因为测试而更改方法访问修饰符。
这样的事情:
Method method = obj1.getClass().getMethod("getDefaultABC");
method.setAccessible(true);
HelperABC abc = (HelperABC) method.invoke(obj1);
答案 2 :(得分:1)
使方法受保护
protected static HelperABC getDefaultABC() {
return something; // this is a very complicated code
}
然后扩展测试类:
public class testC extends C{
...
}
答案 3 :(得分:0)
如果你可以允许包级别访问,通过遵循SUT和测试类在同一个包(不同的源文件夹)上的测试类的相同包规则,你可以使它更干净恕我直言。