1. JUnit
JUnit是一个Java编程语言的单元测试框架,它是由Kent Beck(极限编程)和Erich Gamma(设计模式)建立,是xUnit 家族中最成功的的一个,大部分的Java IDE都集成了JUnit作为单元测试工具。JUnit提供了一组API,使开发人员能够编写测试用例,进行测试和输出结果。JUnit提供了许多有用的功能,如断言,测试套件和测试运行器。这些功能使得测试更容易、更方便、更可靠。一个典型的单元测试通常可以描述为:“确保方法接受预期范围内的输入,并且为每一次测试输入返回预期的值”,一个标准的测试类如下图所示。
图4-3-1 标准的JUnit测试类
2. JUnit常用注解
JUnit从4.0开始就开始引用了注解的方式来进行单元测试,JUnit5.0常用的注解如下表所示。
表 4-3-1 JUnit 5.0常用的注解
序号 | 注解 | 描述 |
1 | @Test | 表示方法是测试方法。 |
2 | @ParameterizedTest | 表示方法是参数化测试。 |
3 | @RepeatedTest | 表示方法是重复测试 |
4 | @DisplayName | 声明测试类或测试方法的自定义显示名称。 |
5 | @BeforeEach | 表示被注解的方法应在当前类的每个@Test,@RepeatedTest,@ParameterizedTest方法之前执行; 在JUnit 4则为@Before。 |
6 | @AfterEach | 表示被注解的方法应在当前类的每个@Test,@RepeatedTest,@ParameterizedTest方法之后执行; 在JUnit 4则为@After。 |
7 | @BeforeAll | 表示被注解的方法应该在当前类的所有@Test,@RepeatedTest,@ParameterizedTest和方法之前执行; 在JUnit 4则为@BeforeClass。 |
8 | @AfterAll | 表示被注解的方法应该在当前类的所有@Test,@RepeatedTest,@ParameterizedTest和方法之后执行; 在JUnit 4则为@AfterClass。 |
9 | @Nested | 表示被注解的类是一个嵌套的非静态测试类。 |
10 | @Tag | 在类或方法级别声明标签,用于过滤测试。 |
11 | @Disabled | 用于禁用测试类或测试方法; 类似于JUnit4的@Ignore。 |
3. JUnit断言
JUnit主要使用断言来进行单元测试,常见的断言如下表所示。
表 4-3-2 JUnit 常见断言
序号 | 断言 | 描述 |
1 | assertEquals([String message], expected value, actual value) | 检查int, short, long, byte, char或Object等类型的值是否相等,第一个参数是一个可选的字符串消息。 |
2 | assertEquals(double expected value, double actual value, double delta) | 检查指定误差范围内的double类型值是否相等,需要第三个参数delta表示可接受的误差范围。 |
3 | assertNotEquals([String message], expected value, actual value) | 检查值是否不相等,第一个参数是一个可选的字符串消息。 |
4 | assertArrayEquals([String message], expectedArray, resultArray) | 检查两数组内容是否相同 |
5 | assertTrue(boolean condition) | 检查条件是否为真 |
6 | assertFalse(boolean condition) | 检查条件是否为假 |
7 | assertNull(Object object) | 检查对象是否为空 |
8 | assertNotNull(Object object) | 检查对象是否不空 |
9 | assertSame(Object expected, Object actual) | 检查两个变量是否引用同一对象 |
10 | assertNotSame(Object expected, Object actual) | 检查两个变量是否不引用同一对象 |
4.Hamcrest
在实际开发中JUnit的断言可读性并不是很好,在对集合、Map等数据结构进行断言的应用场景中,必须先获取集合内的数据再进行断言不太方便。JUnit引入了Hamcrest框架,Hamcest提供了一套匹配符Matcher ,这些匹配符更接近自然语言,可读性高,更加灵活。JUnit4结合 Hamcrest 提供了一个全新的断言语法——assertThat,程序员可以只使用assertThat一个断言语句,结合Hamcrest 提供的匹配符,就可以表达全部的测试思想。其基本语法为:
assertThat([message,] value, matcher-statement);
v 第一个参数message,为可选参数,为出错是的提示信息;
v value为想要测试的变量;
v matcher-statement为使用 Hamcrest 匹配符来表达的对前面变量所期望的值的声明,如果value值与matcher-statement所表达的期望值相符,则测试成功,否则测试失败。
Hamcrest 提供的常用匹配符具体如下表所示。
表 4-3-3 Hamcrest 提供的常用匹配符
分类 | 匹配符 | 描述 |
一般匹配符 | is | 相当于== |
not | 相当于!= | |
字符串匹配符 | containsString | 包含某字符串 |
endsWith | 以某字符串结尾 | |
startWith | 以某字符串开头 | |
equalTo | 等于某字符串 | |
equalToLgnoringCase | 忽略大小写的情况下 | |
equalToLgnoringWhiteSpace | 忽略头尾任意个空格的情况下 | |
数值相关匹配 | closeTo(x,y) | 所测浮点数在[x-y,x+y]中测试通过 |
greaterThan(x) | 大于x测试通过 | |
lessThan(x) | 小于x测试通过 | |
greaterThanOrEqualTo(x) | 大于等于x测试通过 | |
lessThanOrEqualTo(x) | 小于等于x测试通过 | |
集合相关匹配 | hasItemInArray(element) | 数组含有element测试通过 |
hasItem(element) | 迭代对象含有element测试通过 | |
hasItems(element1,element2) | 迭代对象至少含有element1~2测试通过 | |
containsInAnyOrder(element1~3) | 迭代对象只含有element1~3测试通过 | |
hasEntry(key,value) | 被测Map对象中含有key对应的value测试通过 | |
hasKey(key) | 被测Map对象含有key测试通过 | |
hasValue(value) | 被测对象含有value测试通过 |

