我试图修改System.currentTimeMillis()返回的值,这样我就可以执行如下操作:向数据库写入一些东西,模拟等待5分钟,对数据库执行查询(查询取决于写入值的时间)。
在这个SO线程中建议的代码
ShadowSystemClock shadowClock = Robolectric.shadowOf(SystemClock.class);
shadowClock.setCurrentTimeMillis(1424369871446);
因为删除了shadowOf方法,所以不会编译。尝试其他办法,例如:
ShadowSystemClock shadowClock = new ShadowSystemClock();
shadowClock.setCurrentTimeMillis(1424369871446);
虽然出现了覆盖currentTimeMillis()的问题,但这些问题应该在3.0版时解决。
我可以将PowerMock添加到我的项目中,并在本例中使用它,但如果这可以用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
Code.getSystemTime()正在调用正在测试的代码基。该方法只返回System.currentTimeMillis()。
如果ShadowSystemClock拦截了对currentTimeMillis()的调用,一切似乎都会正常进行。有办法吗?
发布于 2016-03-18 06:56:24
首先,由于SystemClock
是一个完全由静态方法组成的单例类,因此不需要使用shadowOf()
。shadowOf()
仅用于查找对象实例的阴影。要访问SystemClock
的影子静态方法,只需直接调用ShadowSystemClock
的静态方法,而不必通过调用new
实例化ShadowSystemClock
。在您的测试代码中,您应该能够免除对new
的调用,并使用ShadowSystemClock.currentTimeMillis()
重新部署shadowClock.currentTimeMillis()
。
第二,更直接地与您有关System.currentTimeMillis()
被拦截的问题有关--在Robolectric下,这将发生,但只对已被检测的代码发生--也就是说,在被Robolectric的特殊类加载器加载时对其进行了修改。在插装代码中,所有对System.currentTimeMillis()
的调用都被调用ShadowSystemClock.currentTimeMillis()
所取代,这正是您想要的。
因此,为了使您的测试以您想要的方式工作,您需要确保您正在测试的代码是被检测的。默认情况下,不是所有类都是这样的,只有Android类。不幸的是,目前我无法亲自测试这一点,但我相信您可以通过在@Config注释中指定包来测试您自己的应用程序类--例如,如果您将@Config(instrumentedPackages={ "my.application" })
放在测试类或方法上,那么这将告诉Robolectric测试"my.application“包中的所有类。这反过来会导致他们的System.currentTimeMillis()
调用被重定向到ShadowSystemClock.currentTimeMillis()
,这应该是您想要的。
之所以这样做的原因不同,是因为使用Robolectric的类加载器方法,不可能修改java.lang.*
包中的类,因为在安装检测类加载器之前已经加载了它们。有一个长期的想法,尝试用类似于JMockit的方法,在Robolectric中以不同的方式来实现这一点,这样就可以解决这个问题。这意味着您不必显式地检测所有客户端类。然而,现在这是空中楼阁,我不会屏住呼吸等待它--希望上面的这些能解决你眼前的问题。
希望这能有所帮助。
发布于 2015-07-27 17:52:14
您需要使用Shadows.shadowOf()
https://stackoverflow.com/questions/31659771
复制相似问题