在访问私有方法和变量时使用反射API是否合适?

时间:2017-06-21 09:17:23

标签: java reflection junit

我想在编写Junit测试用例时访问类的私有方法。使用反射API是否合适?某处我发现反射API很慢.P

请提出建议。

4 个答案:

答案 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)

理想情况下,您不需要在单元测试中访问任何隐藏变量。但是,如果必须,那么一种可能性是使用包保护可见性(无修饰符)。这样,您的单元测试可以读/写该字段,只要它与被测试的类位于同一个包中。