写在前面:

  在JavaScript代码中,异步运行是很常见的。当你有异步运行的代码时,Jest需要知道它测试的代码何时完成,然后才能继续进行另一个测试。Jest提供了几种方法来处理这个问题。

测试异步代码的三种实现方式:

方法一:回调函数

这是非常常见的通用处理方式,比如你有一个fetchData(callback)的function用来获取数据,并且在获取完成的时候调用callback 函数,你想测试返回的数据是“peanut butter” ,默认情况下当fetchData执行完成的时候Jest的测试就完成了,这并不是你所期望的那样的去运行。

// Don't do this!
test('the data is peanut butter', () => {
function callback(data) {
expect(data).toBe('peanut butter');
} fetchData(callback);
});

上面代码的问题就在于一旦fetchData完成,测试也就执行完成,然后再调用回调。

Jest提供了一种用于测试的实现方式,下面代码 done() 被执行则意味着callback函数被调用。

test('the data is peanut butter', done => {
function callback(data) {
expect(data).toBe('peanut butter');
done();
} fetchData(callback);
});

如果 done 永远都不被调用,那么的测试将会失败,这也正是我们期望的(我们希望callback被调用,并且返回的data是我们期望的值)

方法二:承诺验证

如果你的代码中使用了承诺的方式,处理异步测试将会变得更加简单。Jest从你的测试中返回一个承诺,然后等待承诺被实现,如果没有实现,那么就判断测试是失败的。

还是上面的例子,如果用承诺验证,那么实现将是下面的样子:

test('the data is peanut butter', () => {
expect.assertions(1);
return fetchData().then(data => {
expect(data).toBe('peanut butter');
});
});

assertions(1)代表的是在当前的测试中至少有一个断言是被调用的,否则判定为失败。

如果删掉return语句,那么你的测试将在fetchData完成之前结束。

如果断言的承诺并没有被实现,那么你可以添加 .catch 方法。一定要添加expect,断言验证一定数量的断言被调用。否则一个实现的承诺就不会失败。

test('the fetch fails with an error', () => {
expect.assertions(1);
return fetchData().catch(e => expect(e).toMatch('error'));
});

在Jest 20.0.0+  的版本中你可以使用 .resolves 匹配器在你的expect语句中,Jest将会等待一直到承诺被实现,如果承诺没有被实现,测试将自动失败。

test('the data is peanut butter', () => {
expect.assertions(1);
return expect(fetchData()).resolves.toBe('peanut butter');
});

如果你期望你的承诺是不被实现的,你可以使用 .rejects ,它的原理和 .resolves类似

test('the fetch fails with an error', () => {
expect.assertions(1);
return expect(fetchData()).rejects.toMatch('error');
});

第三种:使用 Async/Await

我相信大家最Async/Await 是比较熟悉的,你可以在测试中使用异步和等待。要编写一个async测试,只需在传递到测试的函数前面使用async关键字。例如上面同样的fetchData场景可以使用下面的实现:

test('the data is peanut butter', async () => {
expect.assertions(1);
const data = await fetchData();
expect(data).toBe('peanut butter');
}); test('the fetch fails with an error', async () => {
expect.assertions(1);
try {
await fetchData();
} catch (e) {
expect(e).toMatch('error');
}
});

当然你也可以将Async Await和 .resolves  .rejects 结合起来(Jest 20.0.0+  的版本)

test('the data is peanut butter', async () => {
expect.assertions(1);
await expect(fetchData()).resolves.toBe('peanut butter');
}); test('the fetch fails with an error', async () => {
expect.assertions(1);
await expect(fetchData()).rejects.toMatch('error');
});

写在最后:

在这些情况下,异步和等待实际上只是与承诺示例使用的相同逻辑的语法糖。

这几种方法中没有一个特别优于另外一个,你可以将它们组合在一个代码库中,甚至可以在单个文件中进行匹配。它只是取决于哪种样式使你的测试更简单。

系列教程:

   1. 前端测试框架Jest系列教程 -- Matchers(匹配器)

   2.前端测试框架Jest系列教程 -- Asynchronous(测试异步代码)

   3.前端测试框架Jest系列教程 -- Mock Functions(模拟器)

   4.前端测试框架Jest系列教程 -- Global Functions(全局函数)

前端测试框架Jest系列教程 -- Asynchronous(测试异步代码)的更多相关文章

  1. 前端测试框架Jest系列教程 -- 简介

    写在前面: 随着互联网日新月异的发展,用户对于页面的美观度,流畅度以及各方面的体验有了更高的要求,我们的网页不再是简单的承载文字,图片等简单的信息传递给用户,我们需要的是更加美观的页面展示,更快的浏览 ...

  2. 前端测试框架Jest系列教程 -- Matchers(匹配器)

    写在前面: 匹配器(Matchers)是Jest中非常重要的一个概念,它可以提供很多种方式来让你去验证你所测试的返回值,本文重点介绍几种常用的Matcher,其他的可以通过官网api文档查看. 常用的 ...

  3. 前端测试框架Jest系列教程 -- Mock Functions

    写在前面: 在写单元测试的时候有一个最重要的步骤就是Mock,我们通常会根据接口来Mock接口的实现,比如你要测试某个class中的某个方法,而这个方法又依赖了外部的一些接口的实现,从单元测试的角度来 ...

  4. 前端测试框架Jest系列教程 -- Global Functions(全局函数)

    写在前面: Jest中定义了很多全局性的Function供我们使用,我们不必再去引用别的包来去实现类似的功能,下面将列举Jest中实现的全局函数. Jest Global Functions afte ...

  5. 前端测试框架Jest系列教程 -- Expect(验证)

    写在前面 在编写测试时,我们通常需要检查值是否满足某些条件,Jest中提供的expect允许你访问很多“Matchers”,这些“匹配器”允许您验证不同的东西. Expect 可以验证什么 Jest中 ...

  6. 前端测试框架Jest系列教程 -- Mock Functions(模拟器)

    写在前面: 在写单元测试的时候有一个最重要的步骤就是Mock,我们通常会根据接口来Mock接口的实现,比如你要测试某个class中的某个方法,而这个方法又依赖了外部的一些接口的实现,从单元测试的角度来 ...

  7. 前端测试框架jest 简介

    转自: https://www.cnblogs.com/Wolfmanlq/p/8012847.html 作者:Ken Wang 出处:http://www.cnblogs.com/Wolfmanlq ...

  8. 前端测试框架 Jest

    前端测试工具一览 前端测试工具也和前端的框架一样纷繁复杂,其中常见的测试工具,大致可分为测试框架.断言库.测试覆盖率工具等几类.在正式开始本文之前,我们先来大致了解下它们: 测试框架 测试框架的作用是 ...

  9. 转载自-阮一峰-测试框架 Mocha 实例教程

    测试框架 Mocha 实例教程   作者: 阮一峰 日期: 2015年12月 3日 Mocha(发音"摩卡")诞生于2011年,是现在最流行的JavaScript测试框架之一,在浏 ...

随机推荐

  1. JAVA基础知识总结:三

    一.Java语句的执行结构 1.顺序语句 按照顺序从上往下依次执行的语句,中间没有任何的判断和跳转 2.分支语句 根据不同的条件来产生不同的分支 if语句.switch语句 3.循环语句 重复执行某句 ...

  2. linux系统莫名被黑的诡异经历

    2017年10月28日,ssh登录本地虚拟机之后发现主机名被改成了HUAIWEI_P10. 我一个同事用的此款手机,起初怀疑是他,没放心上. 今天(10月30)发现自己ssh登录不上了.恼火了办公室开 ...

  3. Java基础——数据类型

    Java中与C++的区别: 1.Java中没有无符号类型. 2.整型值和布尔值之间不能进行相互转换. 3.Java中不区分变量的定义和声明. 如:在C++中int i = 10;是一个定义,而exte ...

  4. 用ajax的同步请求解决登陆注册需要根据服务器返回数据判断是否能提交的问题

    最近在写www.doubilaile.com的登陆注册.需要用ajax请求服务器判断用户名是否存在,用户名和密码是否匹配,进而提交数据.碰到的问题是异步请求都能成功返回数据,但是该数据不能作为紧接着的 ...

  5. Leetcode题解(33)

    113. Path Sum II 题目 分析: 主要考察二叉树深度优先遍历(DFS),递归调用当前节点的左右结点即可,代码如下(copy网上): /** * Definition for binary ...

  6. App网络管理

    安卓开发一般都需要进行日志管理,常用操作老司机已为你封装完毕,你可以用这份工具进行管理,具体可以查看源码,现在为你开车,Demo传送门. 站点 系统日志输出工具类 → AppKeyBoardMgr g ...

  7. jQuery选择器(层级选择器)第二节

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/stri ...

  8. cocos2d导入iOS原生项目

    最近公司最新发下任务让融合一个cocos2dx写的游戏项目融合进现有项目,当看到要求时内心瞬间无数羊驼奔腾.------ 虽说内心是拒绝的,但是任务已经派发就必须要完成啊.所以在网上搜了大量的融入教程 ...

  9. RE:通过移动端滑动手势实现数据加载

      背景:         基于要尝试的移动端项目需要有一个通过上拉下滑手势达成加载不同数据的功能,其涉及到滑动手势和ajax数据加载方面的知识点.故对整个实现过程做一个记录整理.个人JS功底有限,看 ...

  10. SQL Server 通过SQL脚本启动Broker并设置兼容性

    SQL Server数据库中通过SQL启用Broker 并建立相关队列和服务 兼容代码使其可以在2000库中执行不报错 针对的是2008版本, 如果是其他版本可以改相关版本号和兼容性标记 /***** ...