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

标签 java unit-testing reflection

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

上周我不得不测试一些包,因此编写了一些 JUnit 测试。与往常一样,我使用反射来访问私有(private)字段和方法。但是我检查代码的主管对此并不满意,并告诉我反射 API 不适合用于这种“黑客攻击”。相反,他建议修改生产代码中的可见性。

使用反射真的很糟糕吗?我简直不敢相信-

编辑:我应该提到我被要求所有测试都在一个名为 test 的单独包中(因此使用 protected 可见性例如也不是一个可能的解决方案)

最佳答案

恕我直言,反射实际上应该只是最后的手段,保留用于单元测试遗留代码或您无法更改的 API 的特殊情况。如果您正在测试自己的代码,那么您需要使用反射意味着您的设计是不可测试的,因此您应该修复它而不是求助于反射。

如果您需要在单元测试中访问私有(private)成员,这通常意味着有问题的类具有不合适的接口(interface),和/或试图做太多事情。所以要么应该修改它的接口(interface),要么应该将一些代码提取到一个单独的类中,在那里可以公开那些有问题的方法/字段访问器。

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

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

关于java - 在单元测试中使用反射是不好的做法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2811141/

相关文章:

git - 使用 Gitlab 持续集成设置 PHPUnit

c# - 如何对依赖于 c# 中的身份验证的 MVC Controller 操作进行单元测试?

haskell - 我可以在运行时从 Haskell 程序中反射(reflect)消息吗?

java - 仅通过其简单名称反射性地找到一个类

java - 使用 Java 时是否必须显式断开与数据库的连接?

java - 有人可以告诉我我做错了什么吗?通过 LinkedList 进行计数和循环

php - 如何使用其依赖项运行 PHPUnit 测试

scala - 使用新的反射API,如何找到类的主构造函数?

java - Spring Boot 2 的 Redis 健康检查挂起

java - 错误和异常有什么区别?