【发布时间】:2020-04-16 22:53:57
【问题描述】:
我有一个包含一些设置的资源文件。我有一个 ResourceLoader 类,它从这个文件加载设置。这个类目前是一个急切地实例化的单例类。一旦这个类加载,它就会从文件中读取设置(文件路径存储为另一个类中的常量字段)。其中一些设置不适合单元测试。例如,我在这个文件中有线程睡眠时间,对于生产代码来说可能是几个小时,但我希望它是几毫秒的单元测试。所以我有另一个测试资源文件,它有一组不同的值。
如何在单元测试期间将主资源文件与此测试文件交换?该项目是一个 Maven 项目,我使用 TestNG 作为测试框架。以下是我一直在考虑的一些方法,但似乎都不理想:
-
使用
@BeforeSuite,修改FilePath常量变量指向测试文件,使用@AfterSuite指向原始文件。这似乎有效,但我认为因为ResourceLoader类被急切地实例化,不能保证@BeforeSuite方法将始终在ResourceLoader类加载之前执行,因此旧属性可能会在文件之前加载路径变了。尽管大多数编译器仅在需要时才加载类,但我不确定这是否是 Java 规范要求。所以理论上这可能不适用于所有 Java 编译器。 -
将资源文件路径作为命令行参数传递。我可以在 pom.xml 的surefire配置中添加测试资源文件路径作为命令行参数。这似乎有点过分了。
-
使用 1. 中的方法并使
ResourceLoader惰性实例化。这保证了如果在第一次调用ResourceLoader.getInstance().getProperty(..)之前调用@BeforeMethod,ResourceLoader将加载正确的文件。这似乎比前两种方法要好,但我认为使单例类延迟实例化会使其变得丑陋,因为我不能使用简单的模式,例如将其设为枚举等(例如急切实例化的情况)。
这似乎是一个常见的场景,最常见的处理方式是什么?
【问题讨论】:
-
是否可以重新设计您的应用程序以使用更好的配置库?
-
是的,我只是想知道执行此操作的标准方法。我愿意重新设计应用程序。
-
唯一的标准方法是使用环境和/或系统属性。这通常过于局限,因为它们很难在例如测试中从命令行提供和覆盖。我建议您在问题中添加有关您需要什么以及您希望如何使用一些用例配置您的应用程序的信息。您可能想考虑在需要它们的类的构造函数中传递配置值。
标签: java unit-testing design-patterns singleton testng