可以使用Clock模拟调用,如使用Clock.millis()
的System.currentTimeMillis()
,并注入Clock的模拟实现。
有没有类似的方法可以轻松地模拟System.nanoTime()
?
使用自己的封装
interface NanoTimer {
long nanoTime();
static NanoTimer system() {
return System::nanoTime;
}
}
这样你就可以很容易地编写自己的mock了。
或者,除了秒表,我看不到任何用例,所以我想你可能想看看Guava的Stopwatch
您可以使用Google Guava的Ticker
类来实现这一点。
或者,如果你只是想正确地测量时间,你可以使用Stopwatch
来获得额外的功能和更好的API,它的构造函数采用Ticker实例。
如果您发现guava-testlib
中的任何其他实用程序都很有用,那么它甚至还有一个FakeTicker
。否则,写一个假的Ticker显然很容易。
您可以在单元测试期间使用依赖项注入接口:
public class YourClass {
private static TimeSupplier timeSupplier = System::nanoTime;
@VisibleForTesting
public static void setTimeSupplier(TimeSupplier timeSupplier) {
YourClass.timeSupplier = timeSupplier;
}
@FunctionalInterface
interface TimeSupplier {
long nanoTime();
}
// Just use timeSupplier.nanoTime() instead of the static nanoTime calls
}
然后,您可以简单地用一个常量(例如Mockito)截断超时:
YourClass.TimeSupplier timeSupplier = mock(YourClass.TimeSupplier.class);
when(timeSupplier.nanoTime()).thenReturn(20221116L);
YourClass.setTimeSupplier(timeSupplier);
使用Clock.instant()
。根据文件:
类存储一个表示epoch秒的long和一个表示第二的纳秒的int
您可以使用Instant.getNano()
访问纳米部件。
它不是等价的,但它是类似的,它为您提供了相同的功能。您甚至不需要读取纳米值,Instant
表示纳米时间。在Instant
类上定义了算术函数,如minus(Instant)
、minusNanos(long)
等。