3.测试环境
第一个例子
我们常用的localStorage进行数据存取,导出 set 和 get 两个函数
添加 src/utils/storage.ts:
// src/utils/storage.ts
export const KEY_NAME = "web-";
const set = (key: string, value: string) => {
localStorage.setItem(KEY_NAME + key, value);
};
const get = (key: string) => {
return localStorage.getItem(KEY_NAME + key);
};
const storage = {
get,
set,
};
export default storage;
添加测试文件: tests/utils/storage.test.ts
// tests/utils/storage.test.ts
import storage from '@utils/storage'
import {KEY_NAME} from "@utils/storage";
describe('storage',()=>{
it('storage存值', function () {
storage.set('name','cw');
expect(localStorage.getItem(KEY_NAME+'name')).toEqual('cw')
});
it('storage取值', function () {
localStorage.setItem(KEY_NAME+'icon','pic');
expect(storage.get('icon')).toEqual('pic')
});
})
运行npm run test跑一下测试,这时候你应该会发现报错了
原因:Node.js 环境并没有 localStorage,所以会得到这样的报错
解决方法:1.我们引入web环境,2.就是我们模拟一下 localStorage,通过mock实现
第一种很简单,在jest.config.js中配置testEnvironment字段。 jsdom这个库用 JS 实现了一套 Node.js 环境下的 Web 标准 API,Jest 用这个库充当了浏览器环境的 Mock 实现。
// jest.config.js
module.exports = {
testEnvironment: "jsdom",
}
第二种没有 localStorage,那就给它 Mock 一个
添加 tests/jest-setup.ts 文件
然后添加 localStorage 的 Mock 实现
// tests/jest-setup.ts
Object.defineProperty(global, 'localStorage', {
value: {
store: {} as Record<string, string>,
setItem(key: string, value: string) {
this.store[key] = value;
},
getItem(key: string) {
return this.store[key];
},
removeItem(key: string) {
delete this.store[key];
},
clear() {
this.store = {}
}
},
configurable: true,
})
这里使用Object.defineProperty()给node全局变量global增加了一个
localStorage,并做了实现
Object.defineProperty()方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象具体详情可以到MDN网站查看一下,vue的双向数据绑定用的也是这个方法实现的,后面改用Proxy特性实现的
接着还需要在jest.config.js中的setupFilesAfterEnv添加mock文件的路径
module.exports = {
setupFilesAfterEnv: ['./tests/jest-setup.ts'],
};
设置了之后,jest-setup.ts 会在每个测试文件执行前先执行一次。 相当于每执行一次测试,都会在全局添加一次 localStorage 的 Mock 实现,再次运行就不会报错了
这里注意一下,还有一个字段setupFiles,它跟setupFilesAfterEnv类似,这里使用setupFiles也是正常的,但是它们的执行时机是不一样的
-
setupFiles是在 引入测试环境(比如下面的jsdom)之后 执行的代码 -
setupFilesAfterEnv则是在 安装测试框架之后 执行的代码
实际使用可以在 setupFiles 可以添加 测试环境 的补充,比如 Mock 全局变量 。在 setupFilesAfterEnv 可以引入和配置一些插件
但如果在 setupFiles 添加 Jest 的扩展/插件,那么可能会得到 expect is not defined 报错,这个时候jest环境还不存在。