一.如何编写单元测试
下面我们以 fetchEnv 方法作为案例,编写一套完整的单元测试用例供读者参考
编写 fetchEnv 方法
./src/utils/fetchEnv.ts
文件
/**
* 环境参数枚举
*/
enum IEnvEnum {
DEV = 'dev', // 开发
TEST = 'test', // 测试
PRE = 'pre', // 预发
PROD = 'prod', // 生产
}
/**
* 根据链接获取当前环境参数
* @param {string?} url 资源链接
* @returns {IEnvEnum} 环境参数
*/
export function fetchEnv(url: string): IEnvEnum {
const envs = [IEnvEnum.DEV, IEnvEnum.TEST, IEnvEnum.PRE];
return envs.find((env) => url.includes(env)) || IEnvEnum.PROD;
}
编写对应的单元测试
./test/fetchEnv.test.ts
文件
import { fetchEnv } from '../src/utils/fetchEnv';
describe('fetchEnv', () => {
it ('判断是否 dev 环境', () => {
expect(fetchEnv('https://www.imooc.dev.com/')).toBe('dev');
});
it ('判断是否 test 环境', () => {
expect(fetchEnv('https://www.imooc.test.com/')).toBe('test');
});
it ('判断是否 pre 环境', () => {
expect(fetchEnv('https://www.imooc.pre.com/')).toBe('pre');
});
it ('判断是否 prod 环境', () => {
expect(fetchEnv('https://www.imooc.prod.com/')).toBe('prod');
});
it ('判断是否 prod 环境', () => {
expect(fetchEnv('https://www.imooc.com/')).toBe('prod');
});
});
执行结果
二.常用断言方法
关于断言方法有很多,这里仅摘出常用方法,如果你想了解更多,你可以去 Jest 官网 API (https://www.jestjs.cn/docs/expect) 部分查看
.not 修饰符允许你测试结果不等于某个值的情况
./test/sum.test.js
import { sum } from './sum';
test('sum(2, 4) 不等于 5', () => {
expect(sum(2, 4)).not.toBe(5);
})
.toEqual 匹配器会递归的检查对象所有属性和属性值是否相等,常用来检测引用类型
./src/utils/userInfo.js
export const getUserInfo = () => {
return {
name: 'moji',
age: 24,
}
}
./test/userInfo.test.js
import { getUserInfo } from '../src/userInfo.js';
test('getUserInfo()返回的对象深度相等', () => {
expect(getUserInfo()).toEqual(getUserInfo());
})
test('getUserInfo()返回的对象内存地址不同', () => {
expect(getUserInfo()).not.toBe(getUserInfo());
})
.toHaveLength 可以很方便的用来测试字符串和数组类型的长度是否满足预期
./src/utils/getIntArray.js
export const getIntArray = (num) => {
if (!Number.isInteger(num)) {
throw Error('"getIntArray"只接受整数类型的参数');
}
return [...new Array(num).keys()];
};
./test/getIntArray.test.js
./test/getIntArray.test.js
import { getIntArray } from '../src/utils/getIntArray';
test('getIntArray(3)返回的数组长度应该为3', () => {
expect(getIntArray(3)).toHaveLength(3);
})
.toThorw 能够让我们测试被测试方法是否按照预期抛出异常
但是需要注意的是:我们必须使用一个函数将被测试的函数做一个包装,正如下面 getIntArrayWrapFn 所做的那样,否则会因为函数抛出错误导致该断言失败。
./test/getIntArray.test.js
import { getIntArray } from '../src/utils/getIntArray';
test('getIntArray(3.3)应该抛出错误', () => {
function getIntArrayWrapFn() {
getIntArray(3.3);
}
expect(getIntArrayWrapFn).toThrow('"getIntArray"只接受整数类型的参数');
})
.toMatch 传入一个正则表达式,它允许我们来进行字符串类型的正则匹配
./test/userInfo.test.js
import { getUserInfo } from '../src/utils/userInfo.js';
test("getUserInfo().name 应该包含'mo'", () => {
expect(getUserInfo().name).toMatch(/mo/i);
})
测试异步函数
./servers/fetchUser.js
/**
* 获取用户信息
*/
export const fetchUser = () => {
return new Promise((resole) => {
setTimeout(() => {
resole({
name: 'moji',
age: 24,
})
}, 2000)
})
}
./test/fetchUser.test.js
import { fetchUser } from '../src/fetchUser';
test('fetchUser() 可以请求到一个用户名字为 moji', async () => {
const data = await fetchUser();
expect(data.name).toBe('moji')
})
这里你可能看到这样一条报错
这是因为 @babel/preset-env
不支持 async await 导致的,这时候就需要对 babel 配置进行增强,可以安装 @babel/plugin-transform-runtime
这个插件解决
npm install --save-dev @babel/plugin-transform-runtime
同时改写 .babelrc
{
"presets": ["@babel/preset-env", "@babel/preset-typescript"],
"plugins": ["@babel/plugin-transform-runtime"]
}
再次运行就不会出现报错了
.toContain 匹配对象中是否包含
./test/toContain.test.js
const names = ['liam', 'jim', 'bart'];
test('匹配对象是否包含', () => {
expect(names).toContain('jim');
})
总结检查一些特殊的值(null,undefined 和 boolean),如下图所示
参考文献
Jest 官方文档 快速入门 · Jest中文文档 | Jest中文网