私はJodaTime2.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();
....
}
_
これにより、SomeTest
の各テストが実行される前に、現在のタイムゾーンがUTCに変更され、各テスト後にデフォルトのタイムゾーンが復元されます。
複数のタイムゾーンを確認する場合は、次のようなルールを使用します。
_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 );
}
_
これにより、UTCを使用してAbstractTZTest
ですべてのテストが実行されます。テストするタイムゾーンごとに、別のクラスが必要になります。
_public class UTCTest extends AbstractTZTest {
@Rule public TZRule tzRule = new TZRule( DateTimeZone.forID( "..." );
}
_
テストケースは継承されるので、それだけです。ルールを定義するだけです。
同様の方法で、システムクロックをシフトできます。 DateTimeUtils.setCurrentMillisProvider(...)
を呼び出してテストが特定の時間に実行されることをシミュレートし、DateTimeUtils.setCurrentMillisSystem()
を呼び出してデフォルトに戻すルールを使用します。
注:プロバイダーには、時計を刻む方法が必要です。そうしないと、すべての新しいDateTime
インスタンスの値が同じになります。 getMillis()
が呼び出されるたびに、値をミリ秒ずつ進めることがよくあります。
注2:これはjoda-timeでのみ機能します。 new Java.util.Date()
には影響しません。
注3:これらのテストを並行して実行することはできなくなりました。それらは順番に実行する必要があります。そうしないと、別のテストの実行中に、そのうちの1つがデフォルトのタイムゾーンに戻る可能性があります。
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()
{
//...
}