为了账号安全,请及时绑定邮箱和手机立即绑定

如何在不引发 org.threeten.bp.zone.ZoneRulesException

如何在不引发 org.threeten.bp.zone.ZoneRulesException

慕田峪7331174 2021-12-10 16:48:33
我有以下应用程序代码。应用代码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;}我用以下内容为它编写了一个单元测试。单元测试代码@Testpublic 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我试图通过使用来修复它单元测试代码@Testpublic 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)
查看完整描述

1 回答

?
弑天下

TA贡献1818条经验 获得超8个赞

ThreeTen-Android Backport 向不支持 Java 8 的 Android 系统提供了 Java SE 8 日期时间类的向后移植。 这个问题的原因是单元测试在 JVM 上运行,而不是 Android开发者所说的:


仅在本地计算机上运行的单元测试。这些测试被编译为在 Java 虚拟机 (JVM) 上本地运行,以最大限度地减少执行时间。如果您的测试依赖于 Android 框架中的对象,我们建议使用 Robolectric。对于依赖于您自己的依赖项的测试,请使用模拟对象来模拟您的依赖项的行为。


Jake Wharton(ThreeTen-Android Backport 所有者)关于没有通过 Robolectric 建立资源说:


这是一个 Robolectric 错误。要么向他们报告,要么切换到在单元测试中使用普通的 ThreeTenBP。或两者!


因此,我们应该使用原始 ThreeTen Backport 库来解决这个问题。所以我们应该将它的依赖添加到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);

}

结果:

//img1.sycdn.imooc.com//61b3148400016f8106630180.jpg

查看完整回答
反对 回复 2021-12-10
  • 1 回答
  • 0 关注
  • 202 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号