@Timeout 是 JUnit 5 用于强制中断超时测试方法的注解,支持方法级和类级配置,默认单位秒,仅作用于测试方法体,通过守护线程调用 interrupt() 实现,需代码响应中断;替代方案 assertTimeout 提供更灵活的超时控制。

在 Java 单元测试中,@Timeout 是 JUnit 5 提供的注解,用于强制中断超时的测试方法,防止因死循环、阻塞 I/O 或无限等待导致测试卡住或长时间挂起。
使用 @Timeout 的基本方式
直接在测试方法上添加 @Timeout,指定最大允许执行时间(单位默认为秒):
-
@Timeout(2)表示该测试最多运行 2 秒,超时则自动失败 - 也可显式指定单位:
@Timeout(value = 500, unit = TimeUnit.MILLISECONDS) - 支持作用于类级别(对所有测试方法生效),但更推荐按需加在具体方法上
@Timeout 的作用范围和限制
@Timeout 只对当前测试方法体内的代码生效,不包括:
- 测试前的
@BeforeEach方法 - 测试后的
@AfterEach方法 - 静态初始化块或
@BeforeAll中的耗时操作
若需控制整个生命周期,需单独为这些钩子方法添加 @Timeout。
立即学习“Java免费学习笔记(深入)”;
与线程中断的关系
@Timeout 底层通过启动一个守护线程,在超时后调用 Thread.interrupt() 中断测试线程:
- 被中断的代码需正确响应中断(如检查
Thread.currentThread().isInterrupted()或捕获InterruptedException) - 若测试中调用了不响应中断的阻塞操作(如某些 native 调用、未处理中断的第三方库),
@Timeout可能无法立即终止 - 中断后测试会抛出
TimeoutException,JUnit 将其视为测试失败
替代方案:使用 assertTimeout 灵活控制
当需要更精细的超时逻辑(比如只对某段代码设限、捕获超时结果做断言),可用 Assertions.assertTimeout:
assertTimeout(Duration.ofSeconds(1), () -> { /* 关键逻辑 */ });-
assertTimeoutPreemptively会主动中断线程(行为类似@Timeout) - 适合在单个测试内对多个子操作分别设限,或结合 try-catch 做恢复处理


















