我想在编写Junit测试用例时访问类的私有方法。使用反射API是否合适?某处我发现反射API很慢.P
请提出建议。
答案 0 :(得分:1)
是的,这种方法完全没问题,我想,对于大多数进行彻底单元测试的项目来说,这种做法并不少见。反射API可能就是为了这个目的而创建的。
为什么你担心反射API变慢?它只会减慢您的测试速度,对于正常运行时的用户来说无关紧要。但是,如果您的测试由于反射API访问而变得太慢,那么只需升级您的开发硬件。我认为它不会成为一个问题,即使你在数以百万计的时间内进行了大量的模块测试。
只是不要更改您的实际非测试程序源代码,例如将所有内容更改为公共,因为您要测试它。这实际上是一件非常糟糕的事情。您需要一个干净的API和干净的类,因此您不希望暴露所有内容。
测试可以并且通常会对您的软件体系结构产生影响,例如鼓励更松散耦合的体系结构,从而使用体系结构模式(如依赖注入)。但是,测试不得定义您的API。 API应该只是你认为它应该是什么,而不是单元测试需要什么(这可能是将所有内容设置为公开,这显然不是语言设计者所期望的,当他们引入私有或受保护的修饰符时)。 p>
然而,在后面的测试阶段,如系统测试,显然不再需要使用反射API,因为您只是触发代码的正常公共API并观察/检查响应。您通常不希望在此测试阶段进入代码并检查其他内容。但是,可能存在某些情况,例如检查您想要仔细检查的标志或非常关键的值。
答案 1 :(得分:0)
根据java上的普通编程流程和junit测试,这是一个不好的做法,你需要验证被测系统(你的类),就像你在你的app中使用它一样。反思打破阶级包容。
如果您想测试某些内容的私有方法,则需要完全重新安排开发工作流程并使用测试驱动开发。示例如何以 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
答案 2 :(得分:-1)
你应该考虑一下你的设计。如果你必须考虑测试私有方法,那么你的类可能会做更多的事情,并且在某些方面违反了SRP。我强烈建议你创建责任较小的新课程。看起来你的课程定义不明确,所以切割它应该没问题。
您可以使用反射测试您的私有方法,但仍然 - 这不是好方法。
答案 3 :(得分:-1)
理想情况下,您不需要在单元测试中访问任何隐藏变量。但是,如果必须,那么一种可能性是使用包保护可见性(无修饰符)。这样,您的单元测试可以读/写该字段,只要它与被测试的类位于同一个包中。