引言
在使用 Jest 对前端代码进行测试时,由于前端代码在浏览器中运行,常常需要用到localStorage,Session,Cookie,indexedDB,Web SQL,操作dom元素等等或者是其他的依赖库,Jest是利用Node.js运行的,node环境并不存在这些东西,我们就需要对它们进行Mock。
以 localStorage 为例
方案1:js-dom
npm i js-dom -D
-
jest.config.js中配置
testEnvironment: "jsdom"
测试代码中就可以直接调用
localStorage.setItem(key, value)
等api
注意: 模拟的localStorage,是在每个测试文件执行前单独加载一次,成为被每个测试文件的一个js模块,因此模拟的localStorage仅可被同一个测试文件中的不同测试单元共享,不能跨文件共享localStorage,其他 api 模拟也是一个道理
js-dom 是一个在node环境下实现了 Web Api 的js库,包含了storage,cookie,dom等,比较完整,如果测试代码中包含了非常多的 web api 调用,建议引入像js-dom这样实现了相关mock的js库。
方案2: 亲手模拟
-
创建localStorage.js,在其中进行简单的实现
Object.defineProperty(global, 'localStorage', { value: { store: {}, setItem(key, value) { this.store[key] = value; }, getItem(key) { return this.store[key]; }, removeItem(key) { delete this.store[key]; }, getAll(){ return this.store; }, clear() { this.store = {} } }, configurable: true, })
-
如果,测试代码中有调用对localStorage操作进行了封装的方法,用和第1步相同的方式把封装的 方法/对象 挂载到全局
我这里封装一个 storage.jsObject.defineProperty(global, 'storage', { value: { set(key, value){ localStorage.setItem(key, value); }, get : (key) => { return localStorage.getItem(key); }, del : (key) => { localStorage.removeItem(key); }, getAll : () => { return localStorage.getAll(); }, }, configurable: true, })
-
jest.config.js 中配置
setupFiles: [ "./test/utils/storage.js", "./test/utils/localStorage.js" ],
放在 setupFilesAfterEnv 中也行,区别不大,setupFiles是在执行时引入测试框架之前就加载
测试代码中就可以调用 localStorage 和 storage
如果我在测试时,只需要少数的简单的 web api,那完全不需要 js-dom 等庞大的js库,亲手实现即可,需要的多且复杂就不建议