代码之家  ›  专栏  ›  技术社区  ›  Shawn D.

当前时间条件下的处理单元测试

  •  15
  • Shawn D.  · 技术社区  · 15 年前

    我正在尝试为我正在处理的项目中的一些实用程序类设置单元测试,其中一个类(包含许可信息)有一个基于当前时间进行确定的方法。

    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 );
    }
    

    1. 我是否应该不必费心测试'isValid',而只需分别测试'isLicenseStringValid()'和'getExpiryDate()'函数?
    2. 我是不是在测试中使用了一个长时间过期的许可证密钥,这样到了过期的时候我就可以换工作了?
    3. 我是否尝试模仿“new Date()”到某个“getCurrentTime()”方法,以便伪造现在的时间?

    其他人通常如何处理有时间条件的测试?

    6 回复  |  直到 10 年前
        1
  •  25
  •   Jon Skeet    15 年前

    绝对是模仿 new Date()

    Clock getCurrentTime() FakeClock 用于测试和 SystemClock 它使用 System.currentTimeMillis() 或者别的什么。

        2
  •  6
  •   Mike Burton    15 年前

    我通常在测试代码中注入一个日期提供者。如果您需要切换约定或以其他方式“修复”时间测试代码,这也会有所帮助。

        3
  •  2
  •   Mitch Wheat    15 年前

    使用依赖注入并注入 TimeProvider 这提供了一个 getExpiryDate()

        4
  •  2
  •   Mahol25    15 年前

    如果你觉得时间提供者/时钟抽象太过完美主义(很可能是这样),那么考虑一下这个

    将getCurrentType protected设为虚拟,然后为包含发布的代码的ProductionType创建TestingProductionType decentant。在该类型中,重写getCurrentType()方法以返回一些确定性结果。在单元测试中,改为创建此TestingProductionType的实例。

    Viola,当前时间的依赖性现在从单元测试中移除了。现在唯一没有单元测试的生产代码是一个单行返回new Date()的方法。我可以接受。

        5
  •  2
  •   HaxElit    15 年前

    如果你能在 http://research.microsoft.com/en-us/projects/pex/ Moles allows to replace any .NET method with a delegate

    -劳尔

        6
  •  1
  •   mdma    15 年前

    这三种方法都是可行的:

    1. 不要测试:懒人的方式
    2. 使用一个在你离开工作之前不会过期的许可证:掩护我
    3. 对当前日期使用mock,例如TimeProvider:完美主义的方式

    isValid() 没有参数覆盖调用 isValid(new Date()) . 测试代码使用以当前日期为参数的版本。