在单元测试中使用反射是不好的实践吗?

8 浏览
0 Comments

在单元测试中使用反射是不好的实践吗?

这个问题已经有答案了::

如何测试具有私有方法、字段或内部类的类?

在过去的几年中,我一直认为在 Java 中,反射在单元测试中被广泛使用。由于需要检查的一些变量/方法是私有的,因此有必要读取它们的值。我一直认为反射 API 也是用于这个目的的。

上周我需要测试一些包,并因此编写了一些 JUnit 测试。像往常一样,我使用反射来访问私有字段和方法。但是我的主管对此并不是很满意,并告诉我,反射 API 并不意味着要用于这种 \"黑客\"。相反,他建议在生产代码中修改可见性。

使用反射真的是坏习惯吗?我真的不太相信。

编辑:我应该提到我要求所有测试都在一个名为“test”的单独包中(因此使用受保护的可见性等并不是可能的解决方案)。

admin 更改状态以发布 2023年5月22日
0
0 Comments

仅仅为了测试而修改生产 API 的可见性是非常不好的做法。该可见性很可能由于合法的原因而被设置为其当前值,不应被更改。

使用反射进行单元测试大多数情况下是可以的。当然,你应该 为了可测试性设计你的类,以减少需要使用反射的情况。

例如,Spring 有 ReflectionTestUtils。但它的目的是设置依赖的模拟对象,而 Spring 应该注入它们。

这个主题比“做与不做”更深入,关注的是什么应该被测试-内部对象状态是否需要测试;我们是否应该质疑正在测试的类的设计等等。

0
0 Comments

在我看来,反射应该只被视为最后的一种选择,仅用于测试旧代码或无法更改的API等特殊情况。如果您正在测试自己的代码,并需要使用反射,则意味着您的设计不可测试,因此应该修复这个问题,而不是诉诸于反射。

如果您需要在单元测试中访问私有成员,则通常意味着该类的接口不合适,或者试图做太多的事情。因此,它的接口应该被修订,或者一些代码应该被提取到一个单独的类中,并在那里将那些有问题的方法/字段访问器设置为公共。

请注意,在普遍情况下使用反射会导致代码更难理解和维护,并且更加脆弱。通常情况下,编译器可以检测到的一整套错误在使用反射时只会出现为运行时异常。

更新:正如@tackline所指出的,这仅涉及在自己的测试代码中使用反射,而不是测试框架的内部。JUnit(以及可能所有其他类似的框架)使用反射来识别和调用您的测试方法-这是一种合理的和局部化的反射使用。如果不使用反射,提供相同功能和便利性将变得困难或不可能。另一方面,它完全封装在框架实现中,因此不会使我们自己的测试代码变得复杂或牺牲。

0