JUnit中类级变量的行为及测试实例化实践疑问
JUnit测试类中DateTimeFormatter的行为与实践问题
测试类代码示例
class testClass{ DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern(settings.getFormatFromUser()); @Test public void test01(){ // ...业务逻辑 DateTime date = dateTimeFormatter.print(new DateTime()); // ...业务逻辑 } // 另一个使用该格式化器的测试方法 @Test public void test02(){ // ...业务逻辑 dateTimeFormatter.print(new DateTime()); // ...业务逻辑 } }
问题1:测试执行过程中通过UI修改格式化字符串会出现什么情况?
结合JUnit的运行机制来看:
- JUnit 4默认会为每个测试方法创建一个独立的测试类实例。你的代码中
dateTimeFormatter是实例成员变量,会在每个测试类实例创建时完成初始化,读取当时settings中的格式化字符串。 - 若在
test01执行过程中修改了格式化字符串:test01中已经初始化好的dateTimeFormatter不会受到影响,因为DateTimeFormatter是不可变类,一旦创建就固定了格式,后续配置修改不会改变它的行为。- 当
test02开始执行时,JUnit会新建一个testClass实例,此时settings.getFormatFromUser()会读取修改后的新格式,所以test02使用的是更新后的格式化器。
- 如果
dateTimeFormatter被定义为static类级变量,那么整个测试类生命周期内只会初始化一次,所有测试方法共享同一个实例。这种情况下,即使中途修改了格式化字符串,已创建的格式化器也不会更新,后续测试方法依然会使用最初的格式。
问题2:格式化器实例化放在测试方法中还是类级别,哪种属于良好实践?
推荐将格式化器的初始化放在测试方法内部,或者通过@Before注解的方法为每个测试实例初始化,原因如下:
- 符合JUnit测试的隔离性原则:每个测试方法应该独立运行,不依赖其他测试的状态,也不会被其他测试的操作影响。将初始化放在方法内,能确保每个测试使用的格式化器都是基于当前配置的,避免全局配置修改带来的测试污染。
- DateTimeFormatter本身是线程安全的,但如果使用类级(尤其是静态)变量,若测试环境支持并行执行,或者全局配置被意外修改,可能导致测试结果不稳定。
- 灵活性更高:如果后续需要为不同测试方法使用不同格式,在方法内实例化可以直接调整,无需修改类级变量的逻辑。
如果所有测试方法确实需要完全相同的固定格式,且配置不会变化,也可以使用类级实例变量,但要确保初始化时的配置是稳定且不会被测试过程修改的。
内容的提问来源于stack exchange,提问作者Ksushant881
相关产品推荐
相关产品推荐

