我使用JodaTime 2.1和我在寻找一个模式的单元测试代码执行日期/时间的操作,以确保它的所有时区和独立的行为以及DST 。
特别:
- 我怎么能嘲笑系统时钟(所以我没有嘲笑一切,我所说的地方
new DateTime()
来获得当前的时间) - 我该怎么办默认时区相同?
我使用JodaTime 2.1和我在寻找一个模式的单元测试代码执行日期/时间的操作,以确保它的所有时区和独立的行为以及DST 。
特别:
new DateTime()
来获得当前的时间) 您可以使用@Rule
这一点。 下面是该规则的代码:
import org.joda.time.DateTimeZone;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;
public class UTCRule extends TestWatcher {
private DateTimeZone origDefault = DateTimeZone.getDefault();
@Override
protected void starting( Description description ) {
DateTimeZone.setDefault( DateTimeZone.UTC );
}
@Override
protected void finished( Description description ) {
DateTimeZone.setDefault( origDefault );
}
}
您可以使用这样的规则:
public class SomeTest {
@Rule
public UTCRule utcRule = new UTCRule();
....
}
这将当前时区更改为UTC在每次测试之前SomeTest
将被执行,每次测试后,将恢复默认的时区。
如果您想检查几个时区,使用类似这样的规则:
import org.joda.time.DateTimeZone;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;
public class TZRule extends TestWatcher {
private DateTimeZone origDefault = DateTimeZone.getDefault();
private DateTimeZone tz;
public TZRule( DateTimeZone tz ) {
this.tz = tz;
}
@Override
protected void starting( Description description ) {
DateTimeZone.setDefault( tz );
}
@Override
protected void finished( Description description ) {
DateTimeZone.setDefault( origDefault );
}
}
将所有受影响的测试,在抽象基类AbstractTZTest
并扩展它:
public class UTCTest extends AbstractTZTest {
@Rule public TZRule tzRule = new TZRule( DateTimeZone.UTC );
}
这将在执行所有测试AbstractTZTest
与UTC。 对于要测试的每个时区,你需要另一个类:
public class UTCTest extends AbstractTZTest {
@Rule public TZRule tzRule = new TZRule( DateTimeZone.forID( "..." );
}
由于测试用例继承,这就是 - 你只需要定义规则。
以类似的方式,可改变一个系统时钟。 使用调用规则DateTimeUtils.setCurrentMillisProvider(...)
来模拟测试在一定的时间和运行DateTimeUtils.setCurrentMillisSystem()
恢复默认设置。
注意:您的供应商将需要一种方法来使时钟滴答或所有新DateTime
实例将具有相同的值。 我通常由毫秒每次推进值getMillis()
被调用。
注2:只有具有乔达时间工作。 它不影响new java.util.Date()
注3:你已经无法并行运行这些测试。 他们必须按顺序运行或其他测试运行时,其中一人将最有可能恢复默认的时区。
for (String zoneId : DateTimeZone.getAvailableIDs())
{
DateTime testedDate1;
DateTime testedDate2;
try
{
final DateTimeZone tz = DateTimeZone.forID(zoneId);
// your test with testedDate1 and testedDate2
}
catch (final IllegalArgumentException e)
{
// catching DST problem
testedDate1 = testetDate1.plusHours(1);
testedDate2 = testetDate2.plusHours(1);
// repeat your test for this dates
}
}
改变单测试
DateTimeZone default;
DateTimeZone testedTZ;
@Before
public void setUp()
{
default = GateTimeZone.getDefault();
DateTimeZone.setDefault
}
@After
public void tearDown()
{
default = GateTimeZone.setDefault();
DateTimeZone.setDefault(testedTZ)
}
@Test
public void test()
{
//...
}