java - 使用 JUnit/Mockito 来确认 java.util.Timer.schedule() 是否符合预期?

标签 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 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() 但只有在解析另一个传递的字符串之后才能将其反序列化为 ChronoUnit 和相关数量。传入的延迟长度可能有限,但可能从 15 分钟到 8 小时不等。

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

我要测试的内容原则上是否正确,如果是,我该怎么做?

编辑:

道歉。刚刚意识到 delayString 还包括“epochStart”,即延迟应该开始的时间。原始“延迟”的当前计算将改为计算:

InstantWhenDelayExpires = epochStart +(ChronoUnit 的数量)

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

我不认为这让我的问题特别复杂?

最佳答案

but I still feel that my test method should confirm that taskToRun() does indeed run eventually but not before the desired delay has expired



事实上,为了验证你为什么不依赖Timer.schedule(TimerTask task, long delay)指定延迟?
这样你就可以在 ClassUnderTest 中添加一个构造函数对于接受 Timer 的测试你可以在单元测试期间模拟它。
断言Timer执行它的设计目的,您只需验证是否使用正确的参数调用了模拟,尤其是延迟参数。
@Mock
Timer mockedTimer;

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

关于java - 使用 JUnit/Mockito 来确认 java.util.Timer.schedule() 是否符合预期?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51898180/

相关文章:

c++ - 专用线程中 QApplication 中的输入小部件会导致 QTimer 从错误的线程停止

Java收据程序不显示结果

java - RMI 中的 UnsupportedOperationException

java - 对值求和并将其存储到数组中

java - Spring Boot JacksonTester 自定义序列化程序未注册

java - 在 RunWith 注释 : does not find tests (java. lang.Exception 中使用 SerenityParameterizedRunner 进行 junit 测试:未找到匹配的方法)

java - 如何在现有文件的位置创建新目录?

java - 在哪里放置 Maven 参数化 junit 输入 xml 文件

c - 在PIC18F中实现定时器以生成随机数

c# - MVVM Execute 方法每 x 秒/分钟,窗口倒计时