在过去的几年中,我一直认为在Java中,反射在单元测试中被广泛使用。由于一些必须检查的变量/方法是私人的,因此需要读取它们的值。我一直认为Reflection API也用于此目的。
上周我必须测试一些软件包,因此编写一些JUnit测试。与往常一样,我使用Reflection来访问私人字段和方法。但是,我的主管检查了代码并不满意,并告诉我反射API并非用于这种“黑客行为”。相反,他建议修改生产代码中的可见性。
使用Reflection是否真的是不好的做法?我无法相信 -
恕我直言反射应该只是最后的手段,保留为单元测试遗留代码的特殊情况或API你不能改变。如果您正在测试自己的代码,那么您需要使用Reflection的事实意味着您的设计不可测试,因此您应该修复该问题而不是诉诸Reflection。
如果你需要在你的单元测试中访问私有成员,它通常意味着有问题的类有不合适的接口,并且/或者尝试做太多。所以要么修改它的接口,要么将一些代码提取到一个单独的类中,在那里可以公开那些有问题的方法/字段访问器。
请注意,通常使用反射会导致代码除了更难理解和维护外,还更脆弱。在正常情况下,会有一整套错误被编译器检测到,但使用Reflection时,它们只会出现运行时异常。
仅仅为了测试而修改生产API的可见性是非常糟糕的。出于正当理由,该可见度很可能会设置为当前值,并且不会更改。
使用反射来进行单元测试基本上没问题。当然,你应该设计你的类来进行可测试性,这样就不需要反射。