使用JUnit/Mockito确认java.util.Timer.schedule()执行预期的操作?

使用JUnit/Mockito确认java.util.Timer.schedule()执行预期的操作?,java,junit,timer,mockito,Java,Junit,Timer,Mockito,我在JUnit/Mockito中看到了很多关于基于时间的测试技术的帖子,但是似乎有太多的考虑因素,以至于我对我应该如何思考我自己的测试代码以及我应该如何/确切地测试什么感到困惑 我的测试代码如下: class ClassUnderTest { Clock clock; // Thought this might be a useful DI, but not sure how... String delayString; Timer timer; public

我在JUnit/Mockito中看到了很多关于基于时间的测试技术的帖子,但是似乎有太多的考虑因素,以至于我对我应该如何思考我自己的测试代码以及我应该如何/确切地测试什么感到困惑

我的测试代码如下:

class ClassUnderTest {
    Clock clock; // Thought this might be a useful DI, but not sure how...
    String delayString;
    Timer timer;

    public ClassUnderTest(String delayString, Clock clock) {
        this.clock = clock;
        this.delayString = delayString;
        init();
    }

    private void init() {
        ChronoUnit unit = parseDelayStringToGetUnit(); // Implementation not shown here
        Integer amountOfTime = parseDelayStringToGetAmount(); // Implementation not shown here
        long delay = calculateDelay(unit, amountOfTime); // Implementation not show here
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                taskToRun();
            }
        }, delay);
    }

    private void taskToRun() {
        // Does something after a delay
        // Happy to amend signature to take params or return a value ...
    }
}
诚然,这是非常削减,但我想削减不重要的东西。当实例化时,它的基本功能是调用taskToRun(),但只有在解析传递的另一个字符串后,才能调用该字符串,该字符串可以反序列化为计时单位和关联数量。只可能传入有限的延迟长度,但它们可以从15分钟到8小时不等

我已经读到我不需要测试计时器本身,但我仍然觉得我的测试方法应该确认taskToRun()确实最终会运行,但不是在期望的延迟过期之前。我原以为将java.time.Clock作为依赖项注入传递会有助于基于时间的测试,但目前我看不出(这里)是如何实现的,而且显然它还没有用于任何事情

我想测试的东西原则上正确吗?如果正确,我该怎么做

编辑:

抱歉。刚刚意识到delayString还包括“epochStart”,这是一个从延迟开始的瞬间。原语“延迟”的当前计算将改为计算:

instantWhenDelayExpires=epochStart+(计时单位数量)

然后计时器将使用instantWhenDelayExpires而不是延迟量进行调度

我不认为这会使我的问题变得特别复杂

但我仍然觉得我的测试方法应该能够确认taskToRun() 确实会最终运行,但不会在所需延迟到期之前运行

事实上,为了证实这一点,你为什么不依靠
Timer.schedule(TimerTask任务,长延迟)
指定延迟的时间?
通过这种方式,您可以在
ClassUnderTest
中为您的测试添加一个接受
计时器的构造函数,并且您可以在单元测试期间模拟它。
要断言
计时器
完成了它的设计任务,您只需验证mock是否使用了正确的参数,尤其是延迟参数进行了调用

@Mock
Timer mockedTimer;

@Test
void constructor(){
   long expectedDelay = ...;
   ClassUnderTest objectUnderTest = new ClassUnderTest(..., mockedTimer);
   Mockito.verify(mockedTimer).schedule(Mockito.any(),  expectedDelay);
}

哈,谢谢你的片段,我正要问你-你读我的心!由于在单元测试和TDD方面缺乏专业知识,我需要阅读更多关于Mockito的内容,但我确实得到了您的解释——非常感谢。