用Java测试基于时间的逻辑单元

Ale*_*lex 8 java time unit-testing date

我有一个方法,根据当前日期的不同,对从DB中提取的数据实现不同的逻辑.

我想通过让单元测试创​​建对象来测试它,将它们保存在DB中并调用测试的方法.但是,为了获得可预测的结果,我每次都需要更改系统日期,而且我不知道如何在Java中执行此操作.

建议?

Pet*_*rey 15

您可以使用当前日期生成预期结果.

或者你编写你的系统来使用你在测试时给出它的日期/时间(而不是时钟)这样的时间总是测试所期望的.

我喜欢用的东西

interface TimeSource {
    long currentTimeMS(); // actually I have currentTimeNS
    void currentTimeMS(long currentTimeMS);
}

enum VanillaTimeSource implements TimeSource {
    INSTANCE;

    @Override
    public long currentTimeMS() {
        return System.currentTimeMillis();
    }

    @Override
    public void currentTimeMS(long currentTimeMS) {
        // ignored
    }
}

class FixedTimeSource implements TimeSource {
    private long currentTimeMS;
    @Override
    public long currentTimeMS() {
        return currentTimeMS;
    }

    @Override
    public void currentTimeMS(long currentTimeMS) {
        this.currentTimeMS =              currentTimeMS;
    }
}
Run Code Online (Sandbox Code Playgroud)

在测试中,我使用FixedTimeSource,它可以是数据驱动的,例如由输入/事件设置.在生产中我使用VanillaTimeSource.INSTANCE忽略输入/事件中的时间并使用当前时间.


Jef*_*ter 8

您需要在类中注入一些内容,以便自定义Time的呈现方式.

例如

public interface TimeProvider {
   DateTime getCurrentTime();
}

public class UnderTest {

  // Inject this in some way (e.g. provide it in the constructor)
  private TimeProvider timeProvider;

  public void MyMethod() {
     if (timeProvider.getCurrentTime() == "1234") {
        // Do something
     }
  }
}
Run Code Online (Sandbox Code Playgroud)

现在,在您的单元测试中,您可以提供时间提供程序的虚假实现.在实际生产代码中,您只需返回当前日期时间即可.