使用Jest测试JavaScript (入门篇)

1 什么是 Jest?

image_1cm920qh8c84igb1o1lbsi16jb16.png-43.4kB

Jest是 Facebook 的一套开源的 JavaScript 测试框架, 它自动集成了断言、JSDom、覆盖率报告等开发者所须要的全部测试工具,是一款几乎零配置的测试框架。而且它对一样是 Facebook 的开源前端框架 React 的测试十分友好。前端

2 安装Jest

2.1 初始化package.json

shell中输入如下命令,初始化前端项目并生成package.jsonios

npm init -y

2.2 安装Jest及相关依赖

shell中输入如下命令,安装测试所须要的依赖:正则表达式

npm install -D jest babel-jest babel-core babel-preset-env regenerator-runtime

babel-jestbabel-coreregenerator-runtimebabel-preset-env这几个依赖是为了让咱们可使用ES6的语法特性进行单元测试,ES6提供的 import 来导入模块的方式,Jest自己是不支持的。shell

2.3 添加.babelrc文件

在项目的根目录下添加.babelrc文件,并在文件复制以下内容:npm

{
  "presets": ["env"]
}

2.4 修改package.json中的test脚本

打开package.json文件,将script下的test的值修改成jestjson

"scripts": {
  "test": "jest"
}

3. 编写你的第一个Jest测试

建立srctest目录及相关文件axios

  • 在项目根目录下建立src目录,并在src目录下添加functions.js文件
  • 在项目根目录下建立test目录,并在test目录下建立functions.test.js文件

Jest会自动找到项目中全部使用.spec.js.test.js文件命名的测试文件并执行,一般咱们在编写测试文件时遵循的命名规范:测试文件的文件名 = 被测试模块名 + .test.js,例如被测试模块为functions.js,那么对应的测试文件命名为functions.test.js数组

src/functions.js中建立被测试的模块前端框架

export default {
  sum(a, b) {
    return a + b;
  }
}

test/functions.test.js文件中建立测试用例babel

import functions  from '../src/functions';

test('sum(2 + 2) 等于 4', () => {
  expect(functions.sum(2, 2)).toBe(4);
})

运行npm run test, Jest会在shell中打印出如下消息:

PASS  test/functions.test.js
  √ sum(2 + 2) 等于 4 (7ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        4.8s

4.经常使用的几个Jest断言

上面测试用例中的expect(functions.sum(2, 2)).toBe(4)为一句断言,Jest为咱们提供了expect函数用来包装被测试的方法并返回一个对象,该对象中包含一系列的匹配器来让咱们更方便的进行断言,上面的toBe函数即为一个匹配器。咱们来介绍几种经常使用的Jest断言,其中会涉及多个匹配器。

.not

//functions.test.js
import functions  from '../src/functions'

test('sum(2, 2) 不等于 5', () => {
  expect(functions.sum(2, 2)).not.toBe(5);
})

.not修饰符容许你测试结果不等于某个值的状况,这和英语的语法几乎彻底同样,很好理解。

.toEqual()

// functions.js
export default {
  getAuthor() {
    return {
      name: 'LITANGHUI',
      age: 24,
    }
  }
}
// functions.test.js
import functions  from '../src/functions';

test('getAuthor()返回的对象深度相等', () => {
  expect(functions.getAuthor()).toEqual(functions.getAuthor());
})

test('getAuthor()返回的对象内存地址不一样', () => {
  expect(functions.getAuthor()).not.toBe(functions.getAuthor());
})

.toEqual匹配器会递归的检查对象全部属性和属性值是否相等,因此若是要进行应用类型的比较时,请使用.toEqual匹配器而不是.toBe

.toHaveLength

// functions.js
export default {
  getIntArray(num) {
    if (!Number.isInteger(num)) {
      throw Error('"getIntArray"只接受整数类型的参数');
    }

    let result = [];
    for (let i = 0, len = num; i < len; i++) {
      result.push(i);
    }
    
    return result;
  }
}
// functions.test.js
import functions  from '../src/functions';

test('getIntArray(3)返回的数组长度应该为3', () => {
  expect(functions.getIntArray(3)).toHaveLength(3);
})

.toHaveLength能够很方便的用来测试字符串和数组类型的长度是否知足预期。

.toThrow

// functions.test.js
import functions  from '../src/functions';

test('getIntArray(3.3)应该抛出错误', () => {
  function getIntArrayWrapFn() {
    functions.getIntArray(3.3);
  }
  expect(getIntArrayWrapFn).toThrow('"getIntArray"只接受整数类型的参数');
})

.toThorw可可以让咱们测试被测试方法是否按照预期抛出异常,可是在使用时须要注意的是:咱们必须使用一个函数将将被测试的函数作一个包装,正如上面getIntArrayWrapFn所作的那样,不然会由于函数抛出致使该断言失败。

.toMatch

// functions.test.js
import functions  from '../src/functions';

test('getAuthor().name应该包含"li"这个姓氏', () => {
  expect(functions.getAuthor().name).toMatch(/li/i);
})

.toMatch传入一个正则表达式,它容许咱们用来进行字符串类型的正则匹配。

5 测试异步函数

安装axios
这里咱们使用最经常使用的http请求库axios来进行请求处理

npm install axios

编写http请求函数
咱们将请求http://jsonplaceholder.typicode.com/users/1,这是由JSONPlaceholder提供的mock请求地址

image_1cm9b6gjprkq1ij11o48a4b1as01j.png-36.1kB

// functions.js
import axios from 'axios';

export default {
  fetchUser() {
    return axios.get('http://jsonplaceholder.typicode.com/users/1')
      .then(res => res.data)
      .catch(error => console.log(error));
  }
}
// functions.test.js
import functions  from '../src/functions';

test('fetchUser() 能够请求到一个含有name属性值为Leanne Graham的对象', () => {
  expect.assertions(1);
  return functions.fetchUser()
    .then(data => {
      expect(data.name).toBe('Leanne Graham');
    });
})

上面咱们调用了expect.assertions(1),它能确保在异步的测试用例中,有一个断言会在回调函数中被执行。这在进行异步代码的测试中十分有效。

使用asyncawait精简异步代码

test('fetchUser() 能够请求到一个用户名字为Leanne Graham', async () => {
  expect.assertions(1);
  const data =  await functions.fetchUser();
  expect(data.name).toBe('Leanne Graham')
})

固然咱们既然安装了Babel,为什么不使用asyncawait的语法来精简咱们的异步测试代码呢? 可是别忘记都须要调用expect.assertions方法

参考资料

【1】 Jest官方文档(https://jestjs.io/zh-Hans/)
【2】 Jest Crash Course - Unit Testing in JavaScript(https://www.youtube.com/watch...

相关文章
相关标签/搜索