Junit 使用私有setter的单元测试类方法

Junit 使用私有setter的单元测试类方法,junit,mockito,Junit,Mockito,我不熟悉单元测试,在这里我很难理解一个简单的用例。 我将setter声明为private(不希望任何人设置这些变量,Spring除外) 在编写单元测试时,当我想为这些变量设置值时,我不能。一个快速的解决方法是使用公共设置器,但这看起来不太好。我使用Mockito作为模拟框架,使用Junit进行单元测试 谢谢你的帮助 编辑: 使它们受保护或包私有,并将测试与类放在同一个包中 正在测试中 或者使用反射调用setter,就像Spring那样 或者使用Mockito的InjectMocks注释,该注释将

我不熟悉单元测试,在这里我很难理解一个简单的用例。 我将setter声明为private(不希望任何人设置这些变量,Spring除外)

在编写单元测试时,当我想为这些变量设置值时,我不能。一个快速的解决方法是使用公共设置器,但这看起来不太好。我使用Mockito作为模拟框架,使用Junit进行单元测试

谢谢你的帮助

编辑:


使它们受保护或包私有,并将测试与类放在同一个包中 正在测试中

或者使用反射调用setter,就像Spring那样

或者使用Mockito的
InjectMocks
注释,该注释将通过使用反射调用setter来注入模拟依赖项。

不要直接对私有成员进行单元测试

(互联网上对此有很多争论。)

单元测试不一定测试代码中的属性和方法,它们测试代码的功能。具体来说,对象公开的面向外部的业务功能。因此,当您面对需要测试的私人成员时,有两件事是正确的:

  • 业务功能可以根据状态调用该私有功能。因此,如果当前的单元测试没有调用该功能作为代码覆盖率的一部分,那么这些测试不是穷举的,并且存在一个未被测试的状态。创建一个测试,在调用面向公共的功能之前安排该状态,以便间接测试该私有成员
  • 测试是详尽的,业务功能在任何已知条件下都不会实际调用该私有成员。在这种情况下,可以简单地从代码中删除私有成员
  • 面向对象设计的原则适用于单元测试,就像它们适用于任何其他代码一样。封装仍然是封装。如果单元测试强行破坏了封装,那么它们很快就会与被测试的代码紧密耦合,这使得它们变得相当脆弱

    考虑周期中的“重构”步骤。如果测试与被测试组件的私有内部紧密耦合,那么重构该组件将需要更改测试。不只是重构那些测试,而是改变他们正在测试的逻辑。这打破了TDD循环


    将其扩展到一个更大的代码系统中,测试将成为重构代码的障碍,而测试本应是重构代码的一项资产。如果测试只验证生成的外向功能,那么代码的内部可以很容易地重构,并且测试用于验证重构工作。

    对此有何评论:我同意其中一位评论者的意见:他实际上反对使用字段和setter注入,因为构造函数注入使依赖关系更清晰。从哲学上讲,我同意他的观点。实际上,我不同意,因为让构造函数初始化字段是样板代码,如果你对TDD很认真,你应该在更新bean的同时更新测试,所以你永远不会对NullPointerException感到惊讶。我不是在测试私有方法。我试图设置private变量的值(它也有一个private setter)来测试其他公共函数。@AmandepGautam:什么功能设置了这个private成员?什么状态导致该私有成员被设置?我建议对此进行更深入的研究。避免紧密耦合的目标仍然存在。这里的阻塞问题可能不是测试无法安排必要的启动状态,而是需要更改对象,以便更明确地允许达到该状态。(在不了解更多有关对象的信息的情况下,我不能肯定。)可能是测试可以注入的依赖关系?
    private setX(T x) {
        this.x = x;
    }
    
    Class A {
        private Clazz clazz;
        //to be used only by spring
        private setClazz(Clazz clazz) {
            this.clazz = clazz;
        }