Junit5中的断言和校验技术详解
发布时间: 2023-12-23 18:36:25 阅读量: 197 订阅数: 26
Junit入门培训资料(断言相关)
3星 · 编辑精心推荐
# 1. 引言
## 1.1 什么是断言和校验技术
断言和校验技术是软件测试中常用的一种技术,用于判断程序的实际执行结果是否符合预期结果。断言通常用于检查条件的真假,并根据结果来决定测试是否通过,从而提高代码的可靠性。
在单元测试中,断言和校验技术被广泛应用,用于验证被测试代码的正确性。通过断言和校验,我们可以检查方法的返回值、对象的状态、异常的抛出等情况,确保代码的正确性。
## 1.2 Junit5简介
Junit5是最新版本的Java单元测试框架,它提供了许多新的特性和改进,以帮助开发人员更方便地编写和管理单元测试。Junit5 的断言和校验技术在测试中非常重要,它提供了丰富的断言方法来验证代码的正确性。
Junit5的断言方法被设计得非常灵活,可以满足不同类型的测试需求。本文将介绍Junit5中的各种断言方法,并示范其使用方法和场景。通过学习本文,读者将能够更加熟练地使用Junit5进行单元测试,并增加代码的质量和可靠性。接下来,我们将详细介绍Junit5中的基本断言。
# 2. Junit5中的基本断言
JUnit5提供了一系列的断言方法,用于验证程序中的实际结果与期望结果是否一致。下面我们将介绍几个常用的基本断言方法。
### 2.1 断言方法介绍
在JUnit5中,基本的断言方法都位于`org.junit.jupiter.api.Assertions`类中,这些方法都以`assert`开头,通过对比实际结果和期望结果来判断测试是否通过。
### 2.2 assertEquals()方法的使用
`assertEquals()`方法用于比较两个值是否相等。它接受两个参数,分别是期望值和实际值。如果两个值相等,则测试通过;否则,测试失败。
```java
@Test
void testEquals() {
String expected = "Hello";
String actual = "Hello";
assertEquals(expected, actual); // 通过
int expectedNum = 100;
int actualNum = 200;
assertEquals(expectedNum, actualNum); // 失败,输出错误信息
}
```
### 2.3 assertTrue()和assertFalse()方法的使用
`assertTrue()`方法用于验证一个条件是否为真。如果条件为真,则测试通过;否则,测试失败。
`assertFalse()`方法与`assertTrue()`方法相反,用于验证一个条件是否为假。
```java
@Test
void testTrueAndFalse() {
assertTrue(5 > 3); // 通过
assertFalse(2 > 5); // 通过
assertTrue(1 == 1); // 通过
int num = 10;
assertFalse(num > 20); // 通过
}
```
### 2.4 assertNull()和assertNotNull()方法的使用
`assertNull()`方法用于验证一个对象是否为空。如果对象为空,则测试通过;否则,测试失败。
`assertNotNull()`方法与`assertNull()`方法相反,用于验证一个对象是否不为空。
```java
@Test
void testNullAndNotNull() {
String str = null;
assertNull(str); // 通过
String s = "Hello";
assertNotNull(s); // 通过
Object obj = new Object();
assertNull(obj); // 失败,输出错误信息
}
```
### 2.5 assertSame()和assertNotSame()方法的使用
`assertSame()`方法用于验证两个对象是否引用同一个对象。如果两个对象引用同一个对象,则测试通过;否则,测试失败。
`assertNotSame()`方法与`assertSame()`方法相反,用于验证两个对象是否不引用同一个对象。
```java
@Test
void testSameAndNotSame() {
String str1 = "Hello";
String str2 = "Hello";
assertSame(str1, str2); // 通过,str1和str2引用同一个对象
String str3 = new String("Hello");
String str4 = new String("Hello");
assertNotSame(str3, str4); // 通过,str3和str4引用不同的对象
assertSame(str1, str3); // 失败,输出错误信息
}
```
在本章节中,我们介绍了JUnit5中的基本断言方法,包括`assertEquals()`、`assertTrue()`、`assertFalse()`、`assertNull()`、`assertNotNull()`、`assertSame()`和`assertNotSame()`方法。通过使用这些方法,我们可以对程序中的结果进行有效的校验和断言。在下一章节中,我们将介绍JUnit5中的集合断言。
# 3. Junit5中的集合断言
在Junit5中,我们可以使用集合断言来校验集合类型的数据。下面将介绍几个常用的集合断言方法。
#### 3.1 assertArrayEquals()方法的使用
`assertArrayEquals()`方法用于校验两个数组是否相等。它会比较数组的长度、依次比较数组中的每个元素。
```java
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
public class CollectionAssertionTest {
@Test
public void testArrayEquals() {
String[] expected = {"apple", "banana", "orange"};
String[] actual = {"apple", "banana", "orange"};
assertArrayEquals(expected, actual, "两个数组不相等");
}
}
```
代码解析:
- 在`testArrayEquals()`方法中,我们定义了一个预期的字符串数组 `expected` 和一个实际的字符串数组 `actual`。
- 使用 `assertArrayEquals()` 方法来校验这两个数组是否相等,如果不相等会抛出 AssertionError 异常,异常信息为第三个参数传入的字符串。
#### 3.2 assertIterableEquals()方法的使用
`assertIterableEquals()`方法用于校验两个可迭代对象是否相等。可迭代对象包括集合、数组、迭代器等。它会比较对象的迭代顺序和元素个数。
```java
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertIterableEquals;
public class CollectionAssertionTest {
@Test
public void testIterableEquals() {
List<String> expected = Arrays.asList("apple", "banana", "orange");
List<String> actual = Arrays.asList("apple", "banana", "orange");
assertIterableEquals(expected, actual, "两个可迭代对象不相等");
}
}
```
代码解析:
- 在`testIterableEquals()`方法中,我们定义了一个预期的字符串列表 `expected` 和一个实际的字符串列表 `actual`。
- 使用 `assertIterableEquals()` 方法来校验这两个对象是否相等,如果不相等会抛出 AssertionError 异常,异常信息为第三个参数传入的字符串。
#### 3.3 assertLinesMatch()方法的使用
`assertLinesMatch()`方法用于校验两个字符串列表是否匹配。它会比较两个列表的行数、行的顺序和每行的内容。
```java
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertLinesMatch;
public class CollectionAssertionTest {
@Test
public void testLinesMatch() {
List<String> expected = Arrays.asList("apple", "banana", "orange");
List<String> actual = Arrays.asList("apple", "banana", "orange");
assertLinesMatch(expected, actual, "两个字符串列表不匹配");
}
}
```
代码解析:
- 在`testLinesMatch()`方法中,我们定义了一个预期的字符串列表 `expected` 和一个实际的字符串列表 `actual`。
- 使用 `assertLinesMatch()` 方法来校验这两个字符串列表是否匹配,如果不匹配会抛出 AssertionError 异常,异常信息为第三个参数传入的字符串。
以上就是Junit5中的集合断言方法的介绍和使用。通过集合断言,我们可以方便地校验集合类型的数据是否符合预期。
# 4. Junit5中的异常断言
在编写单元测试时,我们经常需要测试某个方法是否能够正确地处理异常情况。在Junit5中,我们可以使用异常断言来验证方法是否抛出了预期的异常。Junit5提供了多个异常断言方法,让我们能够方便地进行异常断言。
#### 4.1 assertThrows()和assertDoesNotThrow()方法的使用
- `assertThrows()`方法用于验证方法是否抛出了预期的异常。如果方法没有抛出预期的异常,或抛出了其他异常,断言将失败。
- `assertDoesNotThrow()`方法用于验证方法是否没有抛出任何异常。如果方法抛出了异常,断言将失败。
让我们通过一个示例来演示这两个方法的使用:
```java
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
public class ExceptionAssertionTest {
@Test
public void testDivideByZero() {
assertThrows(ArithmeticException.class, () -> {
int result = 10 / 0;
});
}
@Test
public void testNoException() {
assertDoesNotThrow(() -> {
int result = 10 / 2;
});
}
}
```
在上面的例子中,我们使用`assertThrows()`方法来验证在除法操作中是否抛出了`ArithmeticException`异常,如果抛出了该异常,断言将通过。
而在第二个测试方法中,我们使用`assertDoesNotThrow()`方法来验证在除法操作中是否没有抛出任何异常,即验证除法操作是否正常执行,如果抛出了异常,断言将失败。
#### 4.2 assertTimeout()和assertTimeoutPreemptively()方法的使用
有时候我们需要测试某个方法的执行时间是否在预期范围内。在Junit5中,我们可以使用`assertTimeout()`方法来设置一个超时时间,如果方法的执行时间超过了这个时间,断言将失败。
同时,Junit5还提供了`assertTimeoutPreemptively()`方法,它使用了一个线程池来执行测试方法,可以在方法执行时间超出限制时立即终止执行。
下面的示例展示了这两个方法的使用:
```java
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.time.Duration;
public class TimeoutAssertionTest {
@Test
public void testTimeout() {
Assertions.assertTimeout(Duration.ofMillis(100), () -> {
// 模拟一个耗时操作
Thread.sleep(200);
});
}
@Test
public void testTimeoutPreemptively() {
Assertions.assertTimeoutPreemptively(Duration.ofMillis(100), () -> {
// 模拟一个耗时操作
Thread.sleep(200);
});
}
}
```
在上面的例子中,我们使用`assertTimeout()`方法设置了一个时间限制为100毫秒的测试,如果耗时操作超过了这个时间,断言将失败。
而在第二个测试方法中,我们使用`assertTimeoutPreemptively()`方法来设置同样的时间限制,但该方法会启动一个独立的线程池来执行测试方法,一旦超时,立即终止执行。
通过使用这两个方法,我们可以对方法的执行时间进行合理的限制,以保证单元测试的效率和稳定性。
本章节中我们介绍了在Junit5中的异常断言技术,包括使用`assertThrows()`和`assertDoesNotThrow()`方法进行异常验证,以及使用`assertTimeout()`和`assertTimeoutPreemptively()`方法进行超时验证。这些断言方法能够帮助我们编写更加严谨和可靠的单元测试,提高代码的质量和稳定性。
# 5. Junit5中的自定义断言
在Junit5中,我们可以通过创建自定义断言来扩展测试框架的功能。自定义断言可以提高代码的可读性和可维护性,同时也可以方便地重用断言逻辑。
### 5.1 创建自定义断言
要创建自定义断言,我们需要创建一个类,并继承`org.junit.jupiter.api.Assertions`类。然后,我们可以添加自定义的静态断言方法,并在其内部实现我们想要的校验逻辑。
下面是一个创建自定义断言类的示例代码:
```java
import org.junit.jupiter.api.Assertions;
public class CustomAssertions extends Assertions {
public static void assertPositiveNumber(int number) {
assertTrue(number > 0, () -> "Expected a positive number, but got: " + number);
}
public static void assertStringLength(String str, int length) {
assertNotNull(str, "The input string should not be null");
assertEquals(length, str.length(), () -> "Expected string length: " + length + ", but actual length: " + str.length());
}
}
```
在上面的代码中,我们创建了两个自定义断言方法:
- `assertPositiveNumber()`用于断言一个整数是否为正数,如果不是,则抛出一个带有自定义错误消息的断言错误。
- `assertStringLength()`用于断言一个字符串的长度是否满足预期,如果不满足,则抛出一个带有自定义错误消息的断言错误。
### 5.2 自定义断言的使用
使用自定义断言非常简单,我们只需要按照正常的断言语法调用自定义断言方法即可。
下面是一个使用自定义断言的示例代码:
```java
import org.junit.jupiter.api.Test;
public class CustomAssertionsTest {
@Test
public void testAssertPositiveNumber() {
int number = 10;
CustomAssertions.assertPositiveNumber(number);
}
@Test
public void testAssertStringLength() {
String str = "Hello, World!";
CustomAssertions.assertStringLength(str, 13);
}
}
```
在上面的代码中,我们使用了自定义断言来断言一个整数是否为正数,以及断言一个字符串的长度是否等于13。如果断言失败,Junit5将会抛出一个带有自定义错误消息的断言错误。
总结:
- 在Junit5中,我们可以创建自定义断言来扩展测试框架的功能。
- 自定义断言可以提高代码的可读性和可维护性,同时也可以方便地重用断言逻辑。
- 创建自定义断言需要继承`org.junit.jupiter.api.Assertions`类,并添加自定义的静态断言方法。
- 使用自定义断言只需要按照正常的断言语法调用自定义断言方法即可。
# 6. Junit5中的参数化测试和断言
在Junit5中,参数化测试是指使用不同的参数多次运行同一个测试方法的测试方式。这使得我们可以在同一个测试方法中测试多组数据,从而减少重复的测试代码,提高测试的覆盖范围。在参数化测试中,我们同样可以结合断言对每组参数进行校验,确保测试的准确性和完整性。
#### 6.1 参数化测试的介绍
参数化测试通过为测试方法提供不同的参数值来多次运行同一个测试方法。在Junit5中,参数化测试通过`@ParameterizedTest`注解来实现,同时配合`@MethodSource`、`@ValueSource`等注解来提供参数源。
#### 6.2 使用@ParameterizedTest注解进行参数化测试
下面是一个简单的示例,演示了如何使用`@ParameterizedTest`注解进行参数化测试:
```java
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class ParameterizedTestDemo {
@ParameterizedTest
@ValueSource(ints = {1, 2, 3, 4, 5})
void testSquare(int value) {
assertEquals(value * value, square(value));
}
int square(int x) {
return x * x;
}
}
```
在上面的示例中,我们使用`@ParameterizedTest`注解标记了参数化测试方法`testSquare()`,并使用`@ValueSource`注解提供了整数参数源。在`testSquare()`方法中,我们通过断言`assertEquals()`对每组参数进行了校验,确保被测试的方法`square()`计算结果的准确性。
#### 6.3 参数化测试中的断言
除了在参数化测试方法中使用断言进行校验,我们还可以结合`ArgumentsAccessor`和`ArgumentsProvider`等Junit5提供的工具来实现更灵活的参数化测试和断言校验。这些工具可以帮助我们在测试中使用不同的参数源,更加方便地进行参数化测试。
通过参数化测试和断言的结合使用,我们可以更全面地对被测试代码进行覆盖和校验,提高测试的效率和准确性。
0
0