《Spring Boot 进阶》系列,共包含以下文章:
如果您觉得这篇文章有用 ✔️ 的话,请给博主一个一键三连 吧 (点赞 、关注 、收藏 )!!!您的支持 将激励 博主输出更多优质内容!!!
单元测试(unit test
)是为了检验程序的正确性。一个单元可能是单个 程序、类、对象、方法 等,它是应用程序的最小可测试部件。
单元测试的必要性如下:
Spring Boot 提供了 spring-boot-starter-test
启动器。通过它,能引入一些有用的测试库,如下所示。
JUnit 是对程序代码进行单元测试的 Java 框架。它用来编写自动化测试工具,降低测试的难度、减少烦琐性,并有效避免出现程序错误。
JUnit 测试是 白盒测试(因为知道测试如何完成功能和完成什么样的功能)。要使用 JUnit,则只需要继承 TestCase 类。
JUnit 提供以下注解。
|
|
---|---|
@BeforeClass | 在所有测试单元前执行一次,一般用来初始化整体的代码。 |
@AfterClass | 在所有测试单元后执行一次,一般用来销毁和释放资源。 |
@Before | 在每个测试单元前执行,一般用来初始化方法。 |
@After | 在每个测试单元后执行,一般用来回滚测试数据 |
@Test | 编写测试用例。 |
@Test(timeout=1000) | 对测试单元进行限时。这里的 1000 1000 1000 表示若超过 1 s 1s 1s 则超时测试失败。 |
@Test(expected=Exception.class) | 指定测试单元期望得到的异常类。如果执行完成后没有抛出指定的异常,则测试失败。 |
@lgnore | 执行测试时将忽略掉此方法。如果用于修饰类,则忽略整个类。 |
@RunWith | 在 JUnit 中有很多 Runner,它们负责调用测试代码。每个 Runner 都有特殊功能,应根据需要选择不同的 Runner 来运行测试代码。 |
Unit 4.4 结合 Hamcrest 提供了一个新的断言语法 assertThat
。使用 assertThat 的一个断言语句结合 Hamcrest 提供的匹配符,就可以表达全部的测试思想。
(1)assertThat 的基本语法
assertThat([value], [matcher statement])
value
:要测试的变量值。matcher statement
:如果 value
值与 matcher statement
所表达的期望值相符,则测试成功,否则失败。简单地说,就是 “两个值进行比较”。(2)一般匹配符
assertThat(testNumber,allOf( greaterThan(5),lessThan(8));
:allOf
表示,所有条件必须都成立,测试才能通过。(3)字符串相关匹配符
assertThat(testString,is("longzhiran"));
:is
表示,如果前面待测的 testString 等于后面给出的 String,则测试通过。(4)数值相关匹配符
assertThat(testDouble,closeTo(1.0,8.8));
:closeTo
表示,如果测试的浮点型数 testDouble 在 1.0 ~ 8.8
之间,则测试通过。(5)collection 相关匹配符
assertThat(mObject,hasEntry("key","value");
:hasEntry 表示,如果测试的 Map 对象 mObect 含有一个键值为 key
对应元素值为 value
的 Entry 项,则测试通过。Mockito 是 GitHub 上使用最广泛的 Mocking 框架。它提供简洁的 API 用来测试。Mockito 简单易学、可读性强、验证语法简洁。
与 JUnit 结合使用,Mockito 框架可以创建和配置 Mock 对象。
JSONPath 是 xPath 在 JSON 中的应用。它的数据结构通常不一定有根元素,它用一个抽象的名字 $
来表示 最外层对象,而且允许使用通配符 *
表示所有的子元素名和数组索引。
JSONPath 表达式可以使用 .
符号解析 JSON,如以下代码:
$.person.card[0].num
或使用 []
符号,如以下代码:
$['person']['card'][0]['num']
在单元测试中可能会产生垃圾数据,可以开启事务功能进行回滚。在方法或类头部添加注解 @Transactional 即可。用法见以下代码:
@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
public class CardRepositoryTest {
@Autowired
private CardRepository cardRepository;
@Test
public void testRollBack(){
//查询操作
Card card = new Card();
card.setNum(3);
cardRepository.save(card);
}
}
上述代码在类上添加了注解 @Transactional,测试完成后就会回滚,不会产生垃圾数据。如果要关闭回滚,则只要加上注解 @Rollback(false)
即可。
如果使用的数据库是 MySQL,有时会发现加了注解 @Transactional 也不会回滚,多数情况下是因为默认引擎不是 InnoDB。