如何测试失效条件?

时间:2011-08-01 08:08:02

标签: java unit-testing

我正在开发一个组件,它提供有限生命周期的令牌,并且在应用程序重启时无需持久化。因此,令牌仅存储在存储器中。每个令牌都由一个密钥标识,并具有相关的生存时间,之后令牌将过期,不能再使用。

我停下来想一想如何测试到期条件是否按计划运行?

  1. 使用System.currentTimeMillis的幼稚实现并未提供适当的方法来注入测试边界的任意时间。
  2. 在测试环境之外添加datetime参数(Calendar,Joda-Time的DateTime等)到适当的方法是没有意义的,因为调用者不知道什么时间它是。
  3. 将系统时间包装在一个可以注入和模拟的类中似乎是要走的路,但感觉有点麻烦。除了测试环境之外,这还需要另一个构造函数作为默认实现。
  4. 将生命周期定义为设置可以使等待时间足够短以使sleep()或忙碌等待合理可靠的解决方案
  5. 我目前倾向于选项4,但我也会了解更多选项!

    过度简化的潦草情节:

    private static final long LIFE_SPAN = 60000;
    private Map<T, Long> bestBeforeDates = new HashMap<T, Long>();
    
    public void add(final T key) {
       bestBeforeDates.put(key, System.currentTimeMillis() + LIFE_SPAN);
    }
    
    public boolean isExpired(final T key) {
      // How to make this fail without waiting for x milliseconds
      return bestBeforeDates.get(key) < System.currentTimeMillis();    
    }
    

1 个答案:

答案 0 :(得分:3)

选项3是最好的IMO。获取当前时间是与其他任何IMO一样的服务。编写Clock接口然后适当伪造它很容易。如果您使用的是体面的DI框架,则不需要其他构造函数 - 只需将系统实现绑定到Clock接口即可,无需进一步更改。

我在很多地方都使用过这种方法而且从不后悔。当然,这取决于你是否已经在其他地方使用依赖注入 - 如果它只是你注入的 依赖关系,那就更难了。