有没有一种方法可以使用 EasyMock/PowerMock 来测试 JUnit 测试中从未使用过默认时区?

Is there a way to test that default TimeZone is never used in a JUnit Test using EasyMock/PowerMock?

我想证明我编写的一段代码不受默认时区(设置为 JVM 属性 或通过 setDefault() 方法设置)的影响单元测试。

有没有办法做到这一点?


这不像在调用该方法之前在测试中设置默认时区那么简单,原因是我正在尝试针对竞争条件测试安全性。例如,考虑以下内容:

Calendar calendar = Calendar.getInstance();
Calendar calendar2 = Calendar.getInstance();

assertEquals(calendar.get(Calendar.DATE), calendar2.get(Calendar.DATE));

这个测试应该通过,但是如果默认时区在两次 getInstance() 调用之间突然发生变化,从格林威治标准时间到新加坡,因为另一段代码 运行 某处改变了默认时区,会发生什么情况?然后我们有一个可能会失败的情况。

我能想到的表明它不会受到所有可能更改影响的唯一方法是以某种方式断言代码不会访问默认时区值,无论它在哪里。

在这种情况下,我会引发竞争条件。您在代码中添加人工方法并使用部分模拟或手动模拟来更改时区。

Calendar calendar = Calendar.getInstance();
changeTimeZone();
Calendar calendar2 = Calendar.getInstance();

assertEquals(calendar.get(Calendar.DATE), calendar2.get(Calendar.DATE));

如果只是想知道在代码执行期间是否在某处调用了 setDefault,则可以使用 PowerMock 模拟 setDefault 并在调用时失败。但是,我不确定 PowerMock 是否可以模拟 java.* 类。您可能需要一个 ByteBuddy 代理。

还有一个陷阱。可以使用系统属性设置默认语言环境。但是,如果属性在两个getInstance()之间改变,则没有关系。