Jest

yuhuo2023-07-28开发库工具库
参考链接

一. 搭建

安装

# 安装jest
npm install jest -D
# 安装 babel,提供对 ES6 和 TypeScript 的支持
npm install @babel/core @babel/preset-env @babel/preset-typescript -D
npm install @types/jest babel-jest -D

配置

babel

// babel.config.json
{
    "presets": [
        [
            "@babel/preset-env",
            {
                "targets": {
                    "node": "current"
                }
            }
        ],
        ["@babel/preset-typescript"]
    ]
}

monorepo

涉及到包引用,Jest 会在 node_modules 中查找。

假设 monorepo 的 A 包引用 B 包,虽然 B 的软链接安装在 A 的 node_modules 中,但是查找的逻辑是找 B 包 package.json 中配置的入口文件,而这个入口文件一般是打包后的。而我们调试是希望直接调用 B 包的源代码,所以需要配置一下路径修改。

A
├── node_modules
│   ├── B
│   │   ├── dist
│   │   │   ├── index.js(打包后的代码,Jest 默认引用这个)
│   │   ├── src
│   │   │   ├── index.ts(源代码的入口,我们希望 Jest 引用的)
│   │   └── package.json(配置入口文件是 dist/index.js)

在根路径的 package.json 配置:

{
	"jest": {
        "moduleNameMapper": {
            "^@yho-vue/(.+)": "<rootDir>/packages/$1/src"
        }
	}
}

运行

1. 直接运行

# 执行所有.spec.ts文件
npx jest
# 执行指定.spec.ts文件
npx jest reactive 

2. script 命令

// package.json
{
"scripts": {
        "test": "jest",
    },
}
npm run test

3. Jest 插件

在 VSCode 中安装 ”Jest“ 插件。在测试用例头部自动显示运行按钮,可以直接运行,或打断点调试运行。

二. 测试代码

index.ts

export function add(a: any, b: any) {
    return a + b;
}

index.spec.ts

import { add } from "../index";

// 测试用例
it("init", () => {
    // 断言
    expect(add(1, 1)).toBe(2);
});

// 定义模块
describe("reactive", () => {
    // 测试用例
    it("happy path", () => {
        const original = { foo: 1 };
        const observed = reactive(original);
		
        expect(observed).not.toBe(original);
        expect(observed.foo).toBe(1);
        
        // 断言对象所有属性
        expect(original).toStrictEqual({
            foo: 1,
        });
    });
    // test 和 it 同样作用
    test("scheduler", () => {
		// 用 jest.fn 传入方法,计算方法被执行次数
        const scheduler = jest.fn(() => {});
        // 未被执行
        expect(scheduler).not.toHaveBeenCalled();
        // 执行1次
        scheduler();
        expect(scheduler).toHaveBeenCalledTimes(1);
        // 执行2次
        scheduler();
        expect(scheduler).toHaveBeenCalledTimes(2);
        
        // 执行过程用抛出错误(匹配错误信息,可选)
        expect(()=> {
            baseParse("<div><span></div>");
        }).toThrow("缺少结束标签:span");
    });

// 定义模块
describe("ref", () => {
    // 模块不限制层数
    describe("simple ref", () => {
        // 只执行该测试用例
        it.only("a", () => {
            let obj = {a: 1, b: 2};
            // 生成对象快照(在对应的.snap文件可以浏览对象的数据)
            // 再此运行时,如果生成快照和之前不一样会报错
            // 如果是有意更新快照,需要手动点“Update SnapShot”
            expect(obj).toMatchSnapshot();
        });
        // 跳过该测试用例
        it.skip("a", () => {});
    });
});

index.spec.ts.snap

// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`codegen string 1`] = `
{
  "a": 1,
  "b": 2,
}
`;
Last Updated 2024/3/14 09:51:53