# JUnit 测试超时 – JUnit5 超时示例

> 原文： [https://howtodoinjava.com/junit/how-to-force-timeout-in-jnuit-testcase-execution/](https://howtodoinjava.com/junit/how-to-force-timeout-in-jnuit-testcase-execution/)

学习编写具有超时行为的 JUnit 测试。 如果任何测试未在给定的时限内完成执行，则 JUnit 将停止执行。 还学习使用断言使用 **JUnit5 测试超时**。

## 1\. 为什么要编写 JUnit 超时测试？

有时，我们必须编写 JUnit 测试，以访问网络上的某些外部系统。 绝对不能 100% 地确定在执行测试用例时这些外部系统将可用。 这就是为什么在编写具有外部依赖项的测试用例时，建议使用 JUnit 框架的`timeout`属性。

这也被认为是 [**JUnit 最佳实践**](//howtodoinjava.com/best-practices/unit-testing-best-practices-junit-reference-guide/ "Unit testing best practices : Junit Reference guide") 。

> 每个 JUnit 测试都在一个新线程中运行。 如果在测试完成之前经过了指定的超时，则将通过`Thread.interrupt()`中断其执行。

## 2\. JUnit 测试超时示例 – `timeout`属性

为了指定某个测试用例的超时周期，在注解`@Test`上提到“`timeout`”属性。 例如，`@Test(timeout = 1000)`。

超时时间以**毫秒**指定。

```java
@Test(timeout = 500)
public void testInfiniteTametakingLoop() throws InterruptedException 
{
	while (true)
	{
		Thread.currentThread().sleep(1000);
	}
}

```

在上述测试中，执行将在 5 秒后超时，并显示以下消息。

```java
java.lang.Exception: test timed out after 5000 milliseconds

```

## 2\. JUnit 全局超时示例 – 超时规则

可以为类中的所有测试定义 **JUnit 规则**，而不是为所有测试分别指定超时属性。

```java
@Rule
public Timeout globalTimeout = Timeout.seconds(2);

@Test 	//Pass
public void testInfiniteTametakingLoop1() throws InterruptedException 
{
	while (true)
	{
		Thread.currentThread().sleep(1000);
	}
}

@Test 	//Fail
public void testInfiniteTametakingLoop2() throws InterruptedException 
{
	while (true)
	{
		Thread.currentThread().sleep(5000);
	}
}

```

在上面的示例中，第一个测试将通过，而第二个测试将失败。

请注意，以上超时时间`@Rule`同样适用于`@Before`和`@After`方法。 因此，请小心使用。

## 4\. 使用断言的 JUnit5 超时

在 [**JUnit5**](https://howtodoinjava.com/junit-5-tutorial/) 中，我们可以使用[断言](https://howtodoinjava.com/junit5/junit-5-assertions-examples/)强制测试超时。

```java
import static java.time.Duration.ofMillis;
import static java.time.Duration.ofMinutes;
import static org.junit.jupiter.api.Assertions.assertTimeout;

@Test
void timeoutNotExceeded() 
{
    //The following assertion succeeds.
    assertTimeout(ofMinutes(2), () -> {
        // Perform task that takes less than 2 minutes.
    });
}

@Test
void timeoutExceeded() 
{
    // The following assertion fails with an error message similar to:
    // execution exceeded timeout of 10 ms by 91 ms
    assertTimeout(ofMillis(10), () -> {
        // Simulate task that takes more than 10 ms.
        Thread.sleep(100);
    });
}

```

学习愉快！