【问题标题】:Java making a method run 1 minute in the future for testing purposes [duplicate]Java使方法在未来运行1分钟以进行测试[重复]
【发布时间】:2020-01-21 10:13:35
【问题描述】:

我有一个 java 方法,我想以某种方式模拟系统时钟以进行测试,所以我可以让该方法返回 1 分钟后的结果。我现在确实想使用一个线程并将时间阻塞一分钟,所以我想知道我是否可以伪造时间并假设已经过去了 1 分钟。

更具体地说,我有一个每 1 分钟运行一次的方法,我想测试它是否在 2 分钟后被调用了两次。

【问题讨论】:

  • 检查stackoverflow.com/questions/5622194/… 是否回答了您的问题。在 Java8 中,您可以使用 java.time.Clock。
  • 不是很清楚。我试图查看图书馆,但我没有看到它是如何设置假时间的
  • 我不知道您使用哪些方法,但假设您使用 Instant.now().getEpochSecond(),您可以重构代码以注入时钟并使用 Instant.now(clock)。 getEpochSecond() 代替。然后在您的测试中,您可以传递一个模拟的 Clock 实例并定义行为。

标签: java


【解决方案1】:

将您的代码重写为不直接使用System.currentTimeMillis()(或您正在使用的任何东西),而是使注入您自己的时间提供程序成为可能。然后你可以轻松地在你的测试中模拟这个提供者

public class YourService {
    public YourService(Supplier<Long> timeSupplier) { // use it like e.g. new YourService(System::currentTimeMillis)
        // ...
    }
}

class TimeSupplierMock {
    private long time; // add getters and setter

    TimeSupplierMock(long time) {
        this.time = time;
    }
}


class MyTest {
    @Test
    public void test() {
        TimeSupplierMock mock = new TimeSupplierMock(0);
        YourService service = new YourService(mock);

        // ...

        mock.setTime(20); // increasing time

}

【讨论】:

  • 我会感谢您简短解释为什么-1 ;)
  • 因为头脑正常的人不会编写自己的“时间提供者”。他们将使用 JodaTime,java.time(两者都提供调整时间的方法),或者如果他们正在使用遗留代码(此时他们不会编写任何测试),java.util.Calendar。没有理由过度设计。
  • 是的,我什至举了一个例子,如何提供这样的System 功能-您可以通过方法参考提供完全相同的 Yoda 功能-您不需要也不应该自己编写一。您应该提供自己的实现的唯一地方是测试类,以免弄脏 hack JVM 来伪造时间或......等待 20 秒 :) 它不是过度工程,它被称为“依赖注入”
  • 我的意思是你的答案是过度工程,因为你提供了一个额外的不必要的抽象层。您不需要TimeSupplier,您需要查看您正在使用的日历实现,然后使用它提供的工具。我敢肯定您谈论“依赖注入”(欢迎来到 5 年前)感觉很聪明,但您的回答是“不必要的代码”。
  • 看看 Joda 为您提供的随心所欲制作的东西 - 一些肮脏的 hack,冻结时间,添加一些偏移量,然后您需要手动解冻它 - 如果您忘记这是灾难.如果您将使用另一种没有此类方法或在许多地方使用许多工具的工具怎么办?如果它们影响整个 JVM 怎么办? 如果时间很关键(这是因为 OP 为什么要测试这个?)对于这样的方法/系统,将其提取到另一个级别对我来说并不是过度设计 - 它为您提供了使用的所有优点依赖注入,无需任何成本
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-28
  • 2020-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多