一尘不染

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

java

在过去的几年中,我一直以为Java在单元测试中广泛使用了反射。由于某些必须检查的变量/方法是私有的,因此某种程度上有必要读取它们的值。我一直以为反射API也用于此目的。

上周,我不得不测试一些软件包,因此编写了一些JUnit测试。一如既往,我使用反射来访问私有字段和方法。但是我检查代码的主管对此并不满意,并告诉我ReflectionAPI并不是要用于这种“黑客”活动。相反,他建议修改生产代码中的可见性。

使用Reflection真的不好吗?我真不敢相信-

编辑:我应该提到我被要求所有测试都放在称为测试的单独程序包中(因此,使用受保护的可见性,例如,也是不可能的解决方案)


阅读 227

收藏
2020-09-08

共1个答案

一尘不染

恕我直言,反射实际上应该只是万不得已,保留用于单元测试遗留代码或无法更改的API的特殊情况。如果您正在测试自己的代码,那么您需要使用Reflection的事实意味着您的设计不可测试,因此您应解决此问题,而不要求助于Reflection。

如果您需要在单元测试中访问私有成员,则通常意味着所涉及的类具有不合适的接口,并且/或者尝试执行过多操作。因此,应该修改其接口,或者应该将某些代码提取到一个单独的类中,在这些类中可以将那些有问题的方法/字段访问器公开。

请注意,在一般情况下使用Reflection会导致代码变得更加困难,除了难以理解和维护之外。在通常情况下,编译器会检测到一整套错误,但是使用反射时,它们只会作为运行时异常而出现。

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

2020-09-08