Vla*_*mir 19 java junit testng jodatime
为了测试与时间相关的代码,最好使用虚拟时钟模式
我们的想法是,我们不使用当前时间new Date,而是从可以用虚拟时钟模拟的时钟返回预定义的固定时间.
现在在Java中我们有JodaTime和DateTimeclass,它允许设置采样时间
DateTimeUtils.setCurrentMillisFixed(today.getMillis());
Run Code Online (Sandbox Code Playgroud)
并将固定时间重置为系统时间:
DateTimeUtils.setCurrentMillisSystem();
Run Code Online (Sandbox Code Playgroud)
现在的问题!
如果它在运行测试时全局设置全局上下文中的固定时间,那么将此技术用于setUp和tearDown方法是多么安全.只要我得到它 - 它只会工作,只要我们没有两个并发测试,这种技术在同一环境中并行运行.
Ren*_*ink 17
您必须确保DateTimeUtils.setCurrentMillisSystem()在tearDown方法中调用它.这样一个测试不会影响另一个测试.tearDown即使测试中发生异常,TestNG也应该调用.
当我想要从一个类中解耦时,我常常喜欢另一种方式System.currentTimeMillis();.我介绍一个接口Clock和一个这样的实现SystemClock:
public interface Clock {
public long getCurrentTimeMillis();
}
public class SystemClock implements Clock {
public long getCurrentTimeMillis(){
return System.currentTimeMillis();
}
}
Run Code Online (Sandbox Code Playgroud)
对于测试,可以很容易地创建一个模拟,该模拟在每次调用或一系列预定义时间返回固定时间.
有些人可能认为引入这样的接口来解耦只有一种方法是过度工程,这会对性能产生影响.但幸运的是我们有一个JIT编译器,因为JIT知道只SystemClock加载了类,所以它知道没有其他实现(目前).在此假设下,它可以使用内联方法.
所以我更喜欢以最佳测试方式编写代码.
编辑
使用Java 8,您可能希望使用该Supplier<Long>接口.
例如,在您的客户端代码中,您可以使用方法引用
public class SomeClass {
private Supplier<Long> currentTimeMillisSupplier;
public SomeClass(){
this(System::currentTimeMillis);
}
SomeClass(Supplier<Long> currentTimeMillisSupplier){
this.currentTimeMillisSupplier = currentTimeMillisSupplier;
}
}
Run Code Online (Sandbox Code Playgroud)
默认构造函数用于"正常"使用,而另一个包作用域构造函数可用于单元测试.只需将测试类放在同一个包中.
你也可以使用Clock界面,因为它是一个@FunctionalInterface.
public class SomeClass {
private Clock clock;
public SomeClass(){
this(System::currentTimeMillis);
}
public SomeClass(Clock clock){
this.clock = clock;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6029 次 |
| 最近记录: |