【jest使用】

Quick Start

安装:
npm install --save-dev jest

让我们开始为一个假设函数编写测试,该函数将两个数字相加。 首先,创建一个 sum.js 文件:

function sum(a, b) {return a + b;
}
module.exports = sum;

然后,创建一个名为 sum.test.js 的文件。jest会自动找对应的test作为测试文件,所以我们这里也使用了.test文件名。 这将包含我们的实际测试:

const sum = require('./sum');test('adds 1 + 2 to equal 3', () => {expect(sum(1, 2)).toBe(3);
});
  • test方法:需要测试的代码
  • expect方法 :预期方法,就是你调用了什么方法,传递了什么参数,得到的预期是什么

将下面的配置部分添加到你的 package.json 里面:

{"scripts": {"test": "jest"}
}

最后,运行 yarn testnpm run test ,Jest将打印下面这个消息:

PASS  ./sum.test.js
✓ adds 1 + 2 to equal 3 (5ms)

若需要每次修改控制台就会自动跑测试代码,可配置:

{"scripts": {"test": "jest --watchAll"}
}
测试覆盖率生成

在jest.config.js里面配置coverageDirectory : "coverage" ,coverageDirectory为输出覆盖信息文件的目录

const {defaults} = require('jest-config');
module.exports = {moduleFileExtensions: [...defaults.moduleFileExtensions, 'ts', 'tsx'],coverageDirectory : "coverage" 
};

使用npx jest --coverage即可生成一个代码测试覆盖率的说明

让jest支持ES6

由于jest不支持ES6,需要配置babel进行ES6的转换

安装依赖:

npm install --save-dev babel-jest @babel/core @babel/preset-env

可以在工程的根目录下创建一个babel.config.js文件用于配置与你当前Node版本兼容的Babel:

// babel.config.js
module.exports = {presets: [['@babel/preset-env',{targets: {node: 'current',},},],],
};

创建jest.config.js

// jest.config.js
const {defaults} = require('jest-config');
module.exports = {moduleFileExtensions: [...defaults.moduleFileExtensions, 'ts', 'tsx']
};
jest中的匹配器(详细可查看官网)

toBe 使用 Object.is 判断是否严格相等。

toEqual 递归检查对象或数组的每个字段。

toBeNull 只匹配 null

toBeUndefined 只匹配 undefined

toBeDefined 只匹配非 undefined

toBeTruthy 只匹配真。

toBeFalsy 只匹配假。

toBeGreaterThan 实际值大于期望。

toBeGreaterThanOrEqual 实际值大于或等于期望值

toBeLessThan 实际值小于期望值。

toBeLessThanOrEqual 实际值小于或等于期望值。

toBeCloseTo 比较浮点数的值,避免误差。

toMatch 正则匹配。

toContain 判断数组中是否包含指定项。

toHaveProperty(keyPath, value) 判断对象中是否包含指定属性。

toThrow 判断是否抛出指定的异常。

toBeInstanceOf 判断对象是否是某个类的实例,底层使用 instanceof

jest进行异步测试(详细可查看官网)

有一个异步请求接口fetchData,对其进行单元测试,代码如下:

//fetchData.js
import axios from 'axios';export const fetchData = (fn)=>{axios.post('接口').then((response)=>{fn(response.data.responseCode);})
}
//fetchData.test.js
import { fetchData } from '../fetchData.js'test('fetchData 测试',()=>{fetchData((res)=>{expect(res).toEqual('接口返回的值');})
})

注意这样写是有问题的,因为方法还没有等到回调,我们的结果已经完成了,所以这时候你对于没测试完,只是方法可用,就返回了测试结果,这种结果是不保证正确的。

方法一:使用单个参数调用 done,而不是将测试放在一个空参数的函数。 Jest会等done回调函数执行结束后,结束测试。

//fetchData.test.js
import { fetchData } from '../fetchData.js'test('fetchData 测试',(done)=>{fetchData((res)=>{expect(res).toEqual(str);done();})
})

方法二:使用Promise的方式,fetchData 不使用回调函数,而是返回一个 Promise

//fetchData.js
export const fetchData = () => {return axios.post('接口');
}

返回一个promise

//fetchData.test.js
test('fetchData 测试', () => {return fetchData().then(res => {expect(res.data.responseCode).toEqual('接口返回的值'); //res.data.responseCode 接口自定义的数据结构
})

不要忘记把 promise 作为返回值⸺如果你忘了 return 语句的话,在 fetchData 返回的这个 promise 被 resolve、then() 有机会执行之前,测试就已经被视为已经完成了。

同样的,可以通过.catch来测试异常情况

//fetchData.test.js
test('fetchData 测试', () => {return fetchData().catch(err => {expect(err).toEqual('error'); 
})

这里需要说明一下,只有出现异常的时候才会走这个方法,若没有出现异常,就不会走这个测试方法,而Jest会默认这个用例通过了测试。因此需要使用expect.assertions(1),这个代码的意思是“断言,必须需要执行一次expect方法才可以通过测试”。

//fetchData.test.js
test('fetchData 测试', () => {expect.assertion(1);return fetchData().catch(err => {expect(err).toEqual('error'); 
})

**方法三:**使用async/await方式

//fetchData.js
export const fetchData = () => {return axios.post('接口');
}

返回一个promise

//fetchData.test.js
test('fetchData 测试', async () => {let res = await fetchData();expect(res.data.responseCode).toEqual('接口返回的值');
})
jest使用Mock进行测试(详细可查看官网)

jest提供了Mock方法,可以通过jest.fn()编写mock方法

const myMock = jest.fn(res => {console.log('mock....')});myMock();  // mock....

通过jest.mock()对已有的方法或模块进行mock

// foo.js
export const foo = () => {//do something...
}// test.js
import { foo } from './foo'
jest.mock('./foo'); //mock foo foo.mockImplementation(() => 42);
foo();  // 42

或者可以这样

// foo.js
export const foo = () => {//do something...
}// test.js
import { foo } from './foo'
jest.mock('./foo', () => { //mock foo return {foo: jest.fn(() => 42);}
});foo();  // 42

注: jest不支持ES6,若要使用import、export等需要进行babel转换

Q&A

1.jest.mock()模块工厂不允许引用任何范围外的变量

例如:

import { demo } from './demo';
import { foo } from './foo';
jest.mock('./foo', () => {demo();
});

此时会报错

The module factory of `jest.mock()` is not allowed to reference any out-of-scope variables.Invalid variable access: strAllowed objects: Array, ArrayBuffer, Atomics, BigInt, BigInt64Array, BigUint64Array, Boolean, Buffer, COUNTER_HTTP_CLIENT_REQUEST, COUNTER_HTTP_CLIENT_RESPONSE, COUNTER_HTTP_SERVER_REQUEST, COUNTER_HTTP_SERVER_RESPONSE, COUNTER_NET_SERVER_CONNECTION, COUNTER_NET_SERVER_CONNECTION_CLOSE, DTRACE_HTTP_CLIENT_REQUEST, DTRACE_HTTP_CLIENT_RESPONSE, DTRACE_HTTP_SERVER_REQUEST, DTRACE_HTTP_SERVER_RESPONSE, DTRACE_NET_SERVER_CONNECTION, DTRACE_NET_STREAM_END, DataView, Date, Error, EvalError, Float32Array, Float64Array, Function, GLOBAL, Generator, GeneratorFunction, Infinity, Int16Array, Int32Array, Int8Array, InternalError, Intl, JSON, Map, Math, NaN, Number, Object, Promise, Proxy, RangeError, ReferenceError, Reflect, RegExp, Set, SharedArrayBuffer, String, Symbol, SyntaxError, TypeError, URIError, URL, URLSearchParams, Uint16Array, Uint32Array, Uint8Array, Uint8ClampedArray, WeakMap, WeakSet, WebAssembly, arguments, clearImmediate, clearInterval, clearTimeout, console, decodeURI, decodeURIComponent, encodeURI, encodeURIComponent, escape, eval, expect, global, isFinite, 
isNaN, jest, parseFloat, parseInt, process, require, root, setImmediate, setInterval, setTimeout, undefined, unescape.Note: This is a precaution to guard against uninitialized mock variables. If it is ensured that the mock is required lazily, variable names prefixed with `mock` (case insensitive) are permitted.

解决方案:

可使用jest.requireActual()

import { demo } from './demo';
import { foo } from './foo';
jest.mock('./foo', () => {const res = jest.requireActual('./demo')res.demo();
});

参考

https://jestjs.io/docs/zh-Hans/getting-started

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/708710.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mallox勒索病毒的最新威胁:如何恢复您的数据?

引言: 在当今数字化时代,网络安全威胁层出不穷,而勒索软件(Ransomware)是其中最为恶劣的一种形式之一。而.Mallox勒索病毒则是近期备受关注的一种勒索软件,其深受全球各地用户的困扰。那么,让我…

VMWare ESXi安装留档

缘起 由于手边的一台Dell R730是三块硬盘raid0 ,把我惊出一身冷汗,准备把它们改组成raid1 或者raid5 。 但是舍不得里面的ESXi 8 ,在寻找能否把raid0改成raid1 还不掉WSXi的方法,很遗憾没有找到。 ESXi软件下载 这样就要重装E…

畅心付推出二维码收款分账,开启简单分账新篇章!

随着商业环境和消费需求的变化,新的商业模式不断涌现,加速产业转型和数字化进程,传统商业模式也在进行变革,比如以往的收租模式就是其中很典型场景之一,如今传统租金也将迎来全面革新。畅心付推出二维码收款分账&#…

『大模型笔记』检索增强生成(RAG):从理论到LangChain实践

检索增强生成(RAG):从理论到LangChain实践 文章目录 一. 什么是检索增强生成(Retrieval-Augmented Generation, RAG)1.1. 问题背景1.2. 解决方案二. 基于LangChain实现的检索增强生成方法2.1. 准备工作2.2. 准备步骤2.3. 第一步:检索2.4. 第二步:增强2.5. 第三步:生成三. 总…

面试中单例模式有几种写法?

“你知道茴香豆的‘茴’字有几种写法吗?” 纠结单例模式有几种写法有用吗?有点用,面试中经常选择其中一种或几种写法作为话头,考查设计模式和coding style的同时,还很容易扩展到其他问题。这里讲解几种猴子常用的写法&…

探讨:围绕 props 阐述 React 通信

在 ✓ 🇨🇳 开篇:通过 state 阐述 React 渲染 中,以 setInterval 为例,梳理了 React 渲染的相关内容。 📢 本篇会 ✓ 🇨🇳 围绕 props 阐述 React 通信 props React 组件使用 pro…

docker安装单机版canal和使用

说明:我安装的组件架构如下: 1、准备一台虚拟机,192.168.2.223,我安装的时候,docker只支持canal1.1.6版本,1.1.7无法使用docker安装.还有一点要补充,就是1.1.6好像不支持es8.0以上版本&#x…

Appium手机Android自动化

目录 介绍 什么是APPium? APPium的特点 环境准备 adb(android调试桥)常用命令 appium图形化简单使用 连接手机模拟器 使用appium桌面端应用程序 ​编辑 整合java代码测试 环境准备 引入所需依赖 书写代码简单启动 ​编辑 Appium元素定位 id定位 介…

前端配置开发环境,新电脑配置前端开发环境,Vue开发环境配置的详细过程(前端开发环境配置,电脑重置后配置前端开发环境)

简介:有时候,我们需要在新电脑 或者 电脑重置后,配置前端开发环境,具体都需要安装什么软件和插件,这里来记录一下(文章适合新手和小白,大佬可以带过)。 ✨前端开发环境,需…

《Spring Security 简易速速上手小册》第3章 用户认证机制(2024 最新版)

文章目录 3.1 认证流程3.1.1 基础知识详解认证流程的核心概念认证流程的步骤 3.1.2 主要案例:内存用户认证案例 Demo:快速启动你的 Spring Boot 守护程序 3.1.3 拓展案例 1:数据库用户认证案例 Demo:让数据库守护你的秘密 3.1.4 拓…

蓝桥杯备赛第二篇(背包问题)

1. 01 背包(采用状态压缩) public static void main(String[] args) {Scanner scanner new Scanner(System.in);int M scanner.nextInt();int N scanner.nextInt();int[] value new int[N 1];int[] weight new int[N 1];int[] dp new int[M 1];…

python的数据结构

文章目录 python的数据结构列表当做堆栈使用将列表当作队列使用 python的数据结构 列表 (List):一种有序的集合,可以包含多个项目。列表中的项目可以轻松地添加、删除或更改。 my_list [1, 2, 3, 4, 5]列表当做堆栈使用 堆栈是一种后进先出&#xff…

代理IP安全问题:在国外使用代理IP是否安全

目录 前言 一、国外使用代理IP的安全风险 1. 数据泄露 2. 恶意软件 3. 网络攻击 4. 法律风险 二、保护国外使用代理IP的安全方法 1. 选择可信的代理服务器 2. 使用加密协议 3. 定期更新系统和软件 4. 注意网络安全意识 三、案例分析 总结 前言 在互联网时代&…

【postgresql 基础入门】带过滤条件的查询,where子句中的操作符介绍,案例展示,索引失效的大坑就在这里

查询数据-过滤数据 ​专栏内容: postgresql内核源码分析手写数据库toadb并发编程 ​开源贡献: toadb开源库 个人主页:我的主页 管理社区:开源数据库 座右铭:天行健,君子以自强不息;地势坤&#…

翻译平台翻译模型大模型 英翻中 en-zh 评测

评测语句 Trump was always bothered by how Trump Tower fell 41 feet short of the General Motors building two blocks north 结论 大模型翻译最佳,第三方里百度次之,翻译模型还不太行 测试过程 翻译模型 facebook mbart-large-50-many-to-many-…

【Unity】实现从Excel读取数据制作年份选择器

效果预览: 此处利用Excel来读取数据来制作年份选择器,具体步骤如下。 如果只是制作年份选择器可以参考我这篇文章:构建简单实用的年份选择器(简单原理示范) 目录 效果预览: 一、 Excel准备与存放 1.1 …

openssl3.2 - exp - calc PE file checksum and SHA3-512

openssl3.2 - exp - calc PE file checksum and SHA3-512 概述 想在程序中, 对自身的PE内容算校验和和HASH, 然后送给服务端判断PE文件是否被修改了. 前几天, 看了一个资料, 里面有算PE校验和的实现. 迁移到自己工程. 但是没有算HASH, 正好已经将openssl官方demo过了一遍, 有…

K8s Pod资源管理组件

目录 Pod基础概念 在Kubrenetes集群中Pod有如下两种使用方式 pause容器使得Pod中的所有容器可以共享两种资源 网络 存储 总结 kubernetes中的pause容器主要为每个容器提供功能 Kubernetes设计这样的Pod概念和特殊组成结构的用意 通常把Pod分为以下几类 自主式Pod 控…

【字符串】-Lc3-无重复字符的最长子串(indexOf(String str, int fromIndex))

写在前面 最近想复习一下数据结构与算法相关的内容,找一些题来做一做。如有更好思路,欢迎指正。 目录 写在前面一、场景描述二、具体步骤1.环境说明2.代码 写在后面 一、场景描述 给定一个字符串,请你找出其中不含有重复字符的 最长子串 &…

input css padding

这样控件会跑出外套控件在HTML JSP里面是经常出现的。但有些外国adobe的as控件不存在这种情况,这是因为内层控件定义的时候不能超出外层控件的范围。 修改下:去掉原来css padding,然后加上宽度和高度