使用ScheduledExecutorService的测试代码(不使用Sleep)

问题描述 投票:6回答:2

我有一个验证对象,该对象通过一系列检查来运行输入。如果输入未通过任何检查,则验证结束。

通过所有检查的输入将根据滑动时间窗口进行分组。当第一个输入到达时,此窗口将启动。所以这是流程:

1)第一个输入到达。2)输入通过所有检查。3)由于没有活动的计时器,因此输入被放入新的篮子中。计时器窗口开始N秒。4)在此计时器窗口内通过所有检查的所有后续输入将被分组到同一篮子中。5)一旦计时器关闭,便发出篮子。6)任何其他有效输入将启动一个新计时器,然后重复该过程。

目前,为了确保有效的输入正确组合在一起,我在单元测试中使用Thread.sleep(即,一旦我发送了许多输入,我会睡几秒钟,然后醒来并确保已分派的篮子包含了所有预期的东西。

[这开始变得烦人,因为我有700多个单元测试,并且每次运行完整套件时,此测试集合都是瓶颈。

时间窗口只是ScheduledExecutorService。为了能够更快地测试此功能,我应该创建一个可设置的时间窗口对象吗?

java multithreading unit-testing junit scheduledexecutorservice
2个回答
5
投票

您的“单元测试”听起来有点像集成测试。您不仅在测试使用ScheduledExecutorService的单元,而且还在测试ScheduledExecutorService本身。

更好的方法是注入 模拟 ScheduledExecutorService。换句话说,您不需要测试定时事件是否确实在四秒后发生。您只需要测试您的单元询问调度程序以在四秒钟后运行它即可。

这就是模拟进入的地方。您注入模拟调度程序,在您的单元上执行一些操作,该操作应使其与调度程序进行交互,然后您可以查询该模拟程序以验证交互是否确实按预期方式发生了。] >

如果操作正确,每个测试用例可以在几毫秒或几微秒而不是几秒钟内完成。


0
投票

ScheduleExecutorService本身可测试非常难。令人沮丧的是,其实现(ScheduledThreadPoolExecutor)确实具有now()方法。原则上,您可以覆盖此设置并控制时间!问题在于该方法是程序包私有的和最终的,因此不能被覆盖。可以使用PowerMock之类的东西来覆盖它。

© www.soinside.com 2019 - 2024. All rights reserved.