繁体   English   中英

使用当前时间条件处理单元测试

[英]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()'不是一个静态的标准。

  1. 我不应该费心去测试'isValid',只是分别测试'isLicenseStringValid()'和'getExpiryDate()'函数吗?
  2. 我是否只是在测试中使用许可证密钥,并且到期时间很长,这样我就可以在到期时切换作业了?
  3. 我是否试图将'new Date()'模拟为某些'getCurrentTime()'方法,以便我可以假装它现在是什么时候?

其他人通常会做什么时间条件的测试?

绝对嘲笑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

这三种方法都是可能的:

  1. 不要测试:懒人的方式
  2. 使用许可证,在你离开工作岗位之前,这种许可证不会过期:用我的方式掩盖
  3. 使用模拟作为当前日期,例如TimeProvider:完美主义者的方式

我要去做一个comprimise:我将当前日期作为参数添加到isExpired方法和isValid方法。 对于您的实时生产代码,添加一个简单的isValid()无参数覆盖,调用isValid(new Date()) 您的测试代码使用以当前日期为参数的版本。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM