[英]Handling unit tests with a condition on the current time
我正在为我正在进行的项目中的某些实用程序类设置单元测试,其中一个类(包含许可信息)有一个方法可以根据当前时间做一些确定。
即许可证包含到期日期,许可证字符串验证该日期,但是查看许可证是否过期的实际逻辑基于当前时间。
public boolean isValid()
{
return isLicenseStringValid() && !isExpired();
}
public boolean isExpired()
{
Date expiry = getExpiryDate();
if( expiry == null ) {
return false;
}
Date now = new Date();
return now.after( expiry );
}
所以,我不知道该怎么做,因为'new Date()'不是一个静态的标准。
其他人通常会做什么时间条件的测试?
绝对嘲笑new Date()
。
使用getCurrentTime()
方法或类似方法创建Clock
接口。 这样你可以有一个用于测试的FakeClock
和一个使用System.currentTimeMillis()
或其他的SystemClock
。
我已经多次这样做了 - 它运作得非常好。 这也是合乎逻辑的 - 实际上你需要一个“当前时间服务”,因此应该像任何其他依赖项一样注入。
我通常会在测试代码中注入日期提供程序。 如果您需要切换约定或以其他方式“修复”时间测试代码,这也会有所帮助。
使用依赖注入和注入TimeProvider
其提供getExpiryDate()
方法。
如果你觉得TimeProvider / Clock抽象太过落实完美主义者(很可能就是这种情况),请考虑改为
使getCurrentType受保护虚拟,然后创建包含您发布的代码的ProductionType的TestingProductionType后代。 在该类型中,重写getCurrentType()方法以返回一些确定性结果。 在单元测试中,改为创建此TestingProductionType的实例。
Viola,当前时间的依赖关系现已从您的单元测试中删除。 现在唯一没有经过单元测试的生产代码是一条返回新Date()的单行方法。 我可以忍受这个。
如果您可以访问http://research.microsoft.com/en-us/projects/pex/查看Moles allows to replace any .NET method with a delegate
使用Moles allows to replace any .NET method with a delegate
只需使用它来替换Date并让它返回您需要的任何内容。 然后你不需要做任何疯狂的事情。
-Raul
这三种方法都是可能的:
我要去做一个comprimise:我将当前日期作为参数添加到isExpired方法和isValid方法。 对于您的实时生产代码,添加一个简单的isValid()
无参数覆盖,调用isValid(new Date())
。 您的测试代码使用以当前日期为参数的版本。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.