どのようにorg.threeten.bp.zone.ZoneRulesExceptionを上昇させることなくZoneId.systemDefaultを使用するユニットテストコードに

Cheokヤンチェン:

私は、次のアプリケーション・コードを持っています。

アプリケーションコード

public static long advanceByMax1HourWithoutOverflow(long currentTimeMillis) {
    ZoneId zoneId = ZoneId.systemDefault();

    ZonedDateTime zonedDateTime = Instant.ofEpochMilli(currentTimeMillis).atZone(zoneId);

    // 0-23
    int hour = zonedDateTime.getHour();

    if (hour < 23) {
        zonedDateTime = zonedDateTime.plusHours(1);
        return zonedDateTime.toInstant().toEpochMilli();
    }

    // 0-59
    int minute = zonedDateTime.getMinute();

    if (minute < 59) {
        zonedDateTime = zonedDateTime.plusMinutes(1);
        return zonedDateTime.toInstant().toEpochMilli();
    }

    return currentTimeMillis;
}

私は次のようにそれのためのユニットテストを書きました。

ユニットテストコード

@Test
public void advanceByMax1HourWithoutOverflow() {
    /*
    27 October 2018
    1540648800000 -> 1540652400000
    22:00 -> 23:00
    */
    long currentTimeMillis = 1540648800000L;
    long expected = 1540652400000L;
    long output = Utils.advanceByMax1HourWithoutOverflow(currentTimeMillis);
    assertEquals(expected, output);

私は、次のエラーを得ました

org.threeten.bp.zone.ZoneRulesException: No time-zone data files registered

私が使用してそれを修正しようとしました

ユニットテストコード

@Test
public void advanceByMax1HourWithoutOverflow() {
    Context context = mock(Context.class);
    AndroidThreeTen.init(context);

    /*
    27 October 2018
    1540648800000 -> 1540652400000
    22:00 -> 23:00
    */
    long currentTimeMillis = 1540648800000L;
    long expected = 1540652400000L;
    long output = Utils.advanceByMax1HourWithoutOverflow(currentTimeMillis);
    assertEquals(expected, output);

私は取得しています

java.lang.ExceptionInInitializerError
    at org.threeten.bp.ZoneRegion.ofId(ZoneRegion.java:143)
    at org.threeten.bp.ZoneId.of(ZoneId.java:358)
    at org.threeten.bp.ZoneId.of(ZoneId.java:286)
    at org.threeten.bp.ZoneId.systemDefault(ZoneId.java:245)

私は私の現在のアプリケーションのメソッドのシグネチャを変更することなく、ユニットテストに合格することができます方法はありますか?私はそのまま私の現在のアプリケーションのメソッドシグネチャを保持したいと思います。

long advanceByMax1HourWithoutOverflow(long currentTimeMillis)

注、私はユニットテストのために使用されているのGradle

implementation 'com.jakewharton.threetenabp:threetenabp:1.1.1'

testImplementation 'junit:junit:4.12'
testImplementation 'org.mockito:mockito-core:2.19.0'
aminography:

ThreeTen-Androidのバックポートは、Java 8をサポートしていないAndroidシステムへのJava SE 8日付時刻クラスのバックポートを提供し、この問題の原因は、に応じてJVM上でユニットテストを実行すると、ないアンドロイドということであるアンドロイド開発者

唯一のローカルマシン上で実行ユニットテスト。これらのテストは、実行時間を最小限にするために、Java仮想マシン(JVM)上でローカルに動作するようにコンパイルされています。あなたのテストは、Androidフレームワーク内のオブジェクトに依存している場合、我々はRobolectricを使用することをお勧めします。ご自身の依存関係に依存テストでは、あなたの依存関係の行動をエミュレートするためにモックオブジェクトを使用します。

ジェイク・ウォートン(ThreeTen-Androidのバックポート所有者)Robolectricによってリソースを創設ないことについては述べています

これはRobolectricのバグです。あなたのユニットテストでは、通常のThreeTenBPを使用するようにレポートまたはスイッチのいずれか。または両方!

その結果として、我々は、元ThreeTenバックポートライブラリを使用することによって、この問題を解決する必要があります。我々はその依存関係を追加する必要がありますのでbuild.gradle、ファイル単位のテストで使用されます。

build.gradleファイルで:

dependencies {

    implementation 'com.jakewharton.threetenabp:threetenabp:1.1.1'

    testImplementation ('org.threeten:threetenbp:1.3.2'){
        exclude group:'com.jakewharton.threetenabp', module:'threetenabp'
    }
}

ユニットテストクラスで:

@Test
public void advanceByMax1HourWithoutOverflow() {
    /*
    27 October 2018
    1540648800000 -> 1540652400000
    22:00 -> 23:00
    */
    long currentTimeMillis = 1540648800000L;
    long expected = 1540652400000L;
    long output = Utils.advanceByMax1HourWithoutOverflow(currentTimeMillis);
    assertEquals(expected, output);
}

結果:

ここでは、画像の説明を入力します。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=178660&siteId=1