我想在编写Junit测试用例时访问类的私有方法。使用反射API是否合适?某处我发现反射API很慢.P
请提出建议。
是的,这种方法完全没问题,我想,对于大多数进行彻底单元测试的项目来说,这种做法并不少见。反射API可能就是为了这个目的而创建的。
为什么你担心反射API变慢?它只会减慢您的测试速度,对于正常运行时的用户来说无关紧要。但是,如果您的测试由于反射API访问而变得太慢,那么只需升级您的开发硬件。我认为这不会成为一个问题,即使你真的花了数百万的模块测试。
只是不要更改您的实际非测试程序源代码,例如将所有内容更改为公共,因为您要测试它。这实际上是一件非常糟糕的事情。您需要一个干净的API和干净的类,因此您不希望公开所有内容。
测试可以,而且通常会对您的软件架构产生影响,例如鼓励更松散耦合的架构,从而使用依赖注入等架构模式。但是,测试不得定义您的API。 API应该只是你认为它应该是什么,而不是单元测试需要什么(可能是将所有内容设置为公开,这显然不是语言设计者的意图,当他们引入私有或受保护的修饰符时)。
然而,在后面的测试阶段,如系统测试,显然不再需要使用反射API,因为您只是触发代码的正常公共API并观察/检查响应。您通常不希望在此测试阶段进入代码并检查其他内容。但是,可能存在某些情况,例如检查要仔细检查的标志或非常关键的值。
根据java上的正常编程流程和junit测试,这是一个不好的做法,尤其需要验证被测系统(您的类),就像您在应用程序中使用它一样。反思打破阶级包容。
如果您想测试某些东西的私有方法,您需要完全重新安排开发工作流程并使用测试驱动开发。示例如何以tdd方式正确测试私有方法。假设我们有A类并测试它:
class A {
public int calculate() {
//very complex code
// 50+ lines of code
}
}
class ATest {
public void shouldCalculateComplexThing() {
A a = new A();
int answer = a.calculate();
Assert.assertEquals(answer, 42);
}
}
在那之后我们提到calculate()
方法太大而无法在第一眼看到并且我们需要重构它:
class A {
public int calculate() {
return calculateFirstPart() + calculateSecondPart();
}
private int calculateFirstPart() {
//code
}
private int calculateSecondPart() {
//code
}
}
因为我们已经对它进行了测试,我们已经有了相同的答案42
,但是我们更改了代码并引入了私有方法,我们不需要测试它,因为它们通过方法calculate()
进行了测试。这是在tdd中测试私有字段,方法和其他类实现细节的正确方法
你应该考虑一下你的设计。如果你必须考虑测试私有方法,那么你的类可能会做更多的事情,并且在某些方面违反了SRP。我强烈建议你创建责任较小的新课程。看起来你的课程定义不明确,所以切割它应该没问题。
您可以使用反射测试您的私有方法,但仍然 - 这不是好方法。
理想情况下,您不需要在单元测试中访问任何隐藏变量。但是,如果必须,那么一种可能性是使用包保护可见性(无修饰符)。这样,只要单元测试与被测试的类位于同一个包中,您的单元测试就可以读/写该字段。