学习编写JUnit 5测试,以测试外部系统和模拟依赖项的超时行为。

1.@Timeout注解

1)JUnit 5使用声明方式来定义给定测试的超时行为,使用@Timeout注解。这与JUnit 4的@Test超时属性不同。

2)配置超时的测试应该失败,如果它的执行时间超过给定的持续时间。测试的执行在主线程中进行。如果超时被超过,主线程将从另一个线程中断。

3)超时持续时间的默认时间单位是秒。我们也可以配置其他时间单位。

4)可以将@Timeout注解应用于:

  • 测试
  • 测试工厂
  • 测试模板
  • 生命周期方法

以下是一些测试的示例,应该在3秒内完成,否则失败。

@Timeout Syntax@BeforeEach @Timeout(2) void setUp() { // 执行超过2s就失败 } @Test @Timeout(3) void someTest() { TimeUnit.SECONDS.sleep(5); } 

上述测试将以java.util.concurrent.TimeoutException失败,原因是:someTest()在3秒后超时。

2.全局超时

  • 要为所有测试和嵌套测试配置超时,我们可以在类级别上应用@Timeout注解。
  • 在类级别上声明的@Timeout注解不会应用于生命周期方法。
  • 我们可以通过在特定测试上应用@Timeout注解来覆盖特定测试的超时。
  • 当与@RepeatedTest或@ParameterizedTest一起使用时,超时应用于每个测试调用。

在给定示例中,testMethodOne将失败,而testMethodTwo将通过。

@Timeout(3) public class TimeoutTests { @Test void testMethodOne() throws InterruptedException { TimeUnit.SECONDS.sleep(5); } @Test @Timeout(5) void testMethodTwo() throws InterruptedException { TimeUnit.SECONDS.sleep(4); } } 

3.Assertions.assertTimeout()

assertTimeout()方法断言的是,执行提供的代码应在给定的超时时间之前完成。

以下给定的测试将会通过,因为方法执行在2秒内完成,而assertTimeout()等待3秒。

@Test void testGetValue() throws InterruptedException { Assertions.assertTimeout(Duration.ofSeconds(3), () -> { getValue(); }); } String getValue() throws InterruptedException { TimeUnit.SECONDS.sleep(2); return ""; } 

4.全局禁用@Timeout

禁用超时在全球范围内特别有用,当使用断点调试应用程序代码或测试代码时。在这种情况下,即使所有其他断言都为真,测试也可能因超时而被标记为失败。

使用junit.jupiter.execution.timeout.mode配置参数来配置超时行为。其值包括:

  • enabled(默认模式)–全局启用超时。
  • disabled–全局禁用超时。
  • disabled_on_debug–如果您的IDE不支持此属性,请使用此配置值。