【问题标题】:JUnit System Date [duplicate]JUnit系统日期[重复]
【发布时间】:2014-05-26 16:24:05
【问题描述】:

我正在尝试为我正在处理的项目中的一些实用程序类设置单元测试,其中一个类具有一种基于当前时间进行某些确定的方法。

public String firstDay() {
    Date dateDuJour = new Date();
    int jourCourant = dateDuJour.getDate();
    if (jourCourant == 1)
        return "firstDay";
    else
        return "otherDay";
}

如何解决单元测试使用的方法的问题,术语 new Date()?

编辑

我不会为了获得更好的 Cobertura 结果或确保某些东西可以通过单元测试而修改工作代码。

【问题讨论】:

  • 只是我的两分钱:我不会修改工作代码以获得更好的 Cobertura 结果,或者确保某些东西可以通过单元测试。单元测试是我们从中受益的工具,而不是相反,我们不应该像链接中的人那样对它感到困惑(答案中的 DateTime 类是设计异常)跨度>

标签: java date junit


【解决方案1】:

我不会为了获得更好的 Cobertura 结果或确保某些东西可以通过单元测试而修改工作代码。

甚至可以修改工作代码以使其更易于测试。 Dependency Injection 模式解决了这样的场景。基本思想很简单:依赖关系从依赖对象传递到提供服务的对象。

【讨论】:

    【解决方案2】:

    我认为if 语句不应该进行单元测试。无论如何,只要您使用new Date(),您的代码就无法测试,因为测试结果将取决于测试运行的星期几。 (另外,您不应该使用已弃用的Date.getDate())。

    我将您的方法分为三种方法:

    private void doSomeAction(Date date) {
      Calendar cal = Calendar.getInstance();
      cal.setTime(date);
      if (cal.get(Calendar.DAY_OF_MONTH) == 1) {
        doSomeActionForFirstDay();
      } else {
        doSomeActionForOtherDays();
      }
    }
    
    public void doSomeActionForFirstDay() {
      // IMPLEMENT AND TEST THIS ONE
    }
    
    public void doSomeActionForOtherDays() {
      // IMPLEMENT AND TEST THIS ONE
    }
    

    只测试第二种和第三种方法。如果你碰巧在你的代码中经常使用成语doSomeAction(new Date()),你总是可以添加第四个方法:

    public void doSomeActionToday() {
      doSomeAction(new Date());
    }
    

    这显然不需要任何测试。

    (或者您可以查看these ways 来操作从System.currentTimeMillis() 读取的时间)

    【讨论】:

    • 重构代码的好主意,但通常将 utils 方法声明为私有。
    【解决方案3】:

    为了更好的可测试性,将日期对象作为参数传递,而不是在内部调用 new Date():

    public String firstDay(Date dateDuJour) {
        int jourCourant = dateDuJour.getDate();
        if (jourCourant == 1)
            return "firstDay";
        else
            return "otherDay";
    }
    

    您的通话将从 firstDay() 更改为 firstDay(new Date())。

    更改代码后,您可以轻松传递模拟的日期对象来测试可能的情况。

    【讨论】:

    • 只是为了简化代码,我向您展示了 firstDay 方法,但在实际情况下,我有以下方法 public void maMethode() { // some code Date dateDuJour = new Date(); int jourCourant = dateDuJour.getDate(); if (jourCourant == 1) { // 一些代码 } else { // 一些代码 } // 一些代码 } thx
    • 解决方案保持不变,将依赖项作为参数注入。您可以将“new Date()”包装在可以在构造函数中或通过 init 方法传递的工厂中,然后您可以将此方法保留为不带参数。或者您按照 Raffaele 的建议编写第二种方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-06
    • 2019-11-18
    • 1970-01-01
    • 2016-08-04
    • 2021-10-24
    相关资源
    最近更新 更多