jset-测试环境

381 阅读2分钟

3.测试环境

第一个例子

我们常用的localStorage进行数据存取,导出 setget 两个函数

添加 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跑一下测试,这时候你应该会发现报错了

image-20220716162601299

原因: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环境还不存在。