Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/209.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 机器人分子3.0:模拟系统.currentTimeMillis()_Android_Unit Testing_Robolectric - Fatal编程技术网

Android 机器人分子3.0:模拟系统.currentTimeMillis()

Android 机器人分子3.0:模拟系统.currentTimeMillis(),android,unit-testing,robolectric,Android,Unit Testing,Robolectric,我正在尝试修改System.currentTimeMillis()返回的值,以便可以执行以下操作:向数据库写入内容、模拟等待5分钟、对数据库执行查询(查询取决于写入值的时间) [此SO线程]中建议的代码: ShadowSystemClock shadowClock = Robolectric.shadowOf(SystemClock.class); shadowClock.setCurrentTimeMillis(1424369871446); 自方法的阴影被删除后未编译。尝试以下替代方案:

我正在尝试修改System.currentTimeMillis()返回的值,以便可以执行以下操作:向数据库写入内容、模拟等待5分钟、对数据库执行查询(查询取决于写入值的时间)

[此SO线程]中建议的代码:

ShadowSystemClock shadowClock = Robolectric.shadowOf(SystemClock.class);
shadowClock.setCurrentTimeMillis(1424369871446);
自方法的阴影被删除后未编译。尝试以下替代方案:

ShadowSystemClock shadowClock = new ShadowSystemClock();
shadowClock.setCurrentTimeMillis(1424369871446);
看起来有,但是这些问题应该从3.0版开始修复

我可以添加到我的项目中,并在这个案例中使用它,但如果这可以通过Robolectric实现,我更愿意这样做

更新:越来越近,但可能遗漏了什么。此代码:

ShadowSystemClock shadowClock = new ShadowSystemClock();

Log("system = " + System.currentTimeMillis() + "; shadow = " + shadowClock.currentTimeMillis() + "; time from code = " + Code.getSystemTime());

shadowClock.setCurrentTimeMillis(50000000L);

Log("system = " + System.currentTimeMillis() + "; shadow = " + shadowClock.currentTimeMillis() + "; time from code = " + Code.getSystemTime());
输出如下:

system = 1438212006879; shadow = 0; time from code = 1438212006894
system = 1438212006898; shadow = 50000000; time from code = 1438212006898
getSystemTime()正在调用正在测试的代码库。该方法只返回System.currentTimeMillis()


如果ShadowSystemClock截获了对currentTimeMillis()的调用,似乎一切都可以正常工作。有办法吗?

您需要使用
Shadows.shadowOf()
首先,因为
SystemClock
是一个完全由静态方法组成的单例类,所以不需要使用
shadowOf()
shadowOf()
仅用于查找对象实例的阴影。要访问
SystemClock
的影子静态方法,只需直接调用
ShadowSystemClock
的静态方法,就不必通过调用
new
来实例化
ShadowSystemClock
。在测试代码中,您应该能够省去对
new
的调用,并使用
ShadowSystemClock.currentTimeMillis()重新访问
shadowClock.currentTimeMillis()

第二,更直接地与您关于被拦截的
System.currentTimeMillis()
的问题有关-在Robolectric下,这将发生,但仅适用于已插入指令的代码-也就是说,在Robolectric的特殊类加载器加载时对其进行修改。在插入指令的代码中,对
System.currentTimeMillis()
的所有调用都将替换为所需的调用
ShadowSystemClock.currentTimeMillis()

因此,为了让您的测试以您想要的方式工作,您需要确保您正在测试的代码已插入指令。默认情况下,Robolectric不会对所有类都执行此操作-仅限Android类。不幸的是,我目前无法亲自测试,但我相信您可以告诉Robolectric通过在@Config注释中指定包来插入您自己的应用程序类,例如,如果您在测试类或方法上放置
@Config(instrumentedPackages={“my.application”})
,然后告诉Robolectric为“my.application”包中的所有类提供工具。这将反过来导致他们的
System.currentTimeMillis()
调用被重定向到
ShadowSystemClock.currentTimeMillis()
,这应该是您想要的

这样做的原因不同,因为使用Robolectric的类加载器方法,不可能修改
java.lang.*
包中的类,因为在安装检测类加载器之前已经加载了这些类。有一个长期的想法,就是尝试在Robolectric中使用类似于JMockit的方法来做不同的事情,这可以绕过这个问题。这意味着您不必显式地对所有客户机类进行指令插入。然而,目前这只是空中楼阁,我不会屏住呼吸等待它的到来——希望上面的内容能解决你眼前的问题


希望这有帮助。

类似这样的内容:Shadows.shadowOf(System.class)?这无法编译,因为它需要一个我不确定如何获取的系统对象。实际上,您可以直接在测试中尝试SystemClock.sleep()吗?我不必将时间提前几秒钟以上,但我希望避免在时间实际提前时等待,从而减慢测试速度:/好的,明白了。在测试中,如果是这种情况,可以尝试ShadowSystemClock.sleep()?调用ShadowSystemClock.sleep()或对ShadowSystemClock实例调用sleep不会修改System.currentTimeMillis()返回的时间:(您能分享您的解决方案吗?使用Roboeletric或PowerMock?我会尝试一下。谢谢!这绝对不能解决问题。System.currentTimeMillis()返回以毫秒为单位的当前时间,而不是由卷影提供的时间。我仅从仪器化环境调用这些方法。我尝试切换到Robolectric 4.0.2,但我看到
ShadowSystemClock#setCurrentTimeMillis
已更改为具有受保护的访问权限-知道为什么或如何克服此问题吗?抱歉,我没有这样做自从3.0以来,我一直在使用Robolectric,所以我不能回答你的问题。我不知道为什么会改变。