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

问题描述 投票:2回答:4

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

请提出建议。

java reflection junit
4个回答
1
投票

是的,这种方法完全没问题,我想,对于大多数进行彻底单元测试的项目来说,这种做法并不少见。反射API可能就是为了这个目的而创建的。

为什么你担心反射API变慢?它只会减慢您的测试速度,对于正常运行时的用户来说无关紧要。但是,如果您的测试由于反射API访问而变得太慢,那么只需升级您的开发硬件。我认为这不会成为一个问题,即使你真的花了数百万的模块测试。

只是不要更改您的实际非测试程序源代码,例如将所有内容更改为公共,因为您要测试它。这实际上是一件非常糟糕的事情。您需要一个干净的API和干净的类,因此您不希望公开所有内容。

测试可以,而且通常会对您的软件架构产生影响,例如鼓励更松散耦合的架构,从而使用依赖注入等架构模式。但是,测试不得定义您的API。 API应该只是你认为它应该是什么,而不是单元测试需要什么(可能是将所有内容设置为公开,这显然不是语言设计者的意图,当他们引入私有或受保护的修饰符时)。

然而,在后面的测试阶段,如系统测试,显然不再需要使用反射API,因为您只是触发代码的正常公共API并观察/检查响应。您通常不希望在此测试阶段进入代码并检查其他内容。但是,可能存在某些情况,例如检查要仔细检查的标志或非常关​​键的值。


0
投票

根据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中测试私有字段,方法和其他类实现细节的正确方法


-1
投票

你应该考虑一下你的设计。如果你必须考虑测试私有方法,那么你的类可能会做更多的事情,并且在某些方面违反了SRP。我强烈建议你创建责任较小的新课程。看起来你的课程定义不明确,所以切割它应该没问题。

您可以使用反射测试您的私有方法,但仍然 - 这不是好方法。


-1
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.