如何用 Jest 模拟 Axios?

2024-01-05

我有一个函数client/index.js这是使用 axios 发出请求

import axios from "axios";

const createRequest = async (url, method) => {
    const response = await axios({
        url: url,
        method: method
    });
    return response;
};

export default { createRequest };

我想使用测试这个功能jest,所以我创建了client/index.test.js

import { jest } from "@jest/globals";
import axios from "axios";
    
import client from "./";

jest.doMock('axios', () => jest.fn(() => Promise.resolve()));

describe("Client", () => {

    it("should call axios and return a response", async () => {
        const response = await client.createRequest('http://localhost/', 'GET');

        expect(axios).toHaveBeenCalled();
    })
})

但是当我尝试运行它时,测试失败并且出现此错误

connect ECONNREFUSED 127.0.0.1:80

如果我使用模拟而不是 doMock,那么我会收到此错误 -

ReferenceError: /Users/project/src/client/index.test.js: The module factory of `jest.mock()` is not allowed to reference any out-of-scope variables.
    Invalid variable access: jest

package.json -

{
    "name": "project",
    "version": "0.0.1",
    "main": "index.js",
    "author": "author",
    "license": "MIT",
    "private": false,
    "type": "module",
    "scripts": {
        "start": "node --experimental-json-modules --experimental-specifier-resolution=node ./src/index.js",
        "start:dev": "nodemon --experimental-json-modules --experimental-specifier-resolution=node ./src/index.js",
        "test": "node --experimental-vm-modules node_modules/.bin/jest",
        "test:dev": "node --experimental-vm-modules node_modules/.bin/jest --watch",
        "test:coverage": "node --experimental-vm-modules node_modules/.bin/jest --coverage",
        "lint": "eslint --fix .",
        "pretty": "prettier --write ."
    },
    "dependencies": {
        "axios": "^0.21.1",
        "express": "^4.17.1"
    },
    "devDependencies": {
        "babel-eslint": "^10.1.0",
        "eslint": "^7.23.0",
        "jest": "^26.6.3",
        "prettier": "^2.2.1",
        "supertest": "^6.1.3"
    },
    "jest": { "testEnvironment": "node" }
}

我在节点环境中运行它,节点版本是14.16.0,开玩笑的版本是26.6.3。 请帮助确定这种方法有什么问题以及如何修复它。


我会推荐一种完全不同的方法来解决这个问题。而不是试图模拟 Axios,这是一个相对复杂的 API,你不拥有,使用类似的工具在网络边界进行测试msw https://mswjs.io/。这允许您自由地重构实现without需要更改测试,让您更有信心它仍然有效。你可以做这样的事情:

  • 分解重复的配置axios.create({ baseURL: "http://localhost", ... });
  • 针对请求切换到不同的库(例如node-fetch).

此外,如果 Axios API 发生更改,您的测试将开始失败,告诉你你的代码不再有效。使用测试替身,因为它仍然会实现以前的 API,所以您将获得通过但具有误导性的测试结果。

这种测试可能是这样的:请注意,Axios 根本没有被提及,它现在只是一个实现细节,我们只关心行为:

import { rest } from "msw";
import { setupServer } from "msw/node";

import client from "./";

const body = { hello: "world" };

const server = setupServer(
  rest.get("http://localhost", (_, res, ctx) => {
    return res(ctx.status(200), ctx.json(body))
  })
);

describe("Client", () => {
    beforeAll(() => server.listen());

    afterEach(() => server.resetHandlers());

    afterAll(() => server.close());

    it("should call the API and return a response", async () => {
        const response = await client.createRequest("http://localhost/", "GET");

        expect(response).toMatchObject({ data: body, status: 200 });
    });
});

注意我必须使用.toMatchObject因为您公开了整个 Axios 响应对象,其中包含很多属性。对于您的客户来说,这不是一个好的 API,因为现在一切使用客户端就是消费Axios API;这会让你与它严重耦合,并削弱我上面提到的好处。

我不确定你打算如何使用它,但我倾向于完全隐藏传输层的细节 - 状态代码、标头等内容可能与消费者中的业务逻辑无关。现在你真的只有:

const createRequest = (url, method) => axios({ method, url });

此时您的消费者可能会直接使用 Axios。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何用 Jest 模拟 Axios? 的相关文章

  • 玉石压痕错误

    因此 对于我的 Express 网站 我使用 jade 所以我决定尝试修改我的布局文件 以便我可以开始设计我的网站 我修改了原始布局代码 有效 但我开始在任何扩展布局的文件中出现缩进错误 如下所示 500 Error home kevin
  • ASP.NET 验证控件和 Javascript 确认框

    我有一个使用 NET 服务器端输入验证控件的页面 此页面还有一个 javascript 确认框 在提交表单时会触发该确认框 当前 当选择 提交 按钮时 会出现 javascript 确认框 一旦确认 就会触发 ASP NET 服务器端验证控
  • 插件 gulp-babel 错误:插件/预设文件不允许导出对象,只能导出函数

    我现在尝试在我的 Ionic v1 应用程序中使用 JavaScript 2015 ES6 包 json name test version 1 0 0 dependencies ionic native deeplinks 4 18 0
  • 修复 Raphaël 路径节点上 Tipsy 工具提示的位置

    这是一个非常具体且有些复杂的问题 所以我设置了一个最小测试用例 http reveal dk 8080 revealit dk tipsytest 在阅读本文的其余部分之前 您可能应该先了解一下 我的页面显示悬停时突出显示区域的图像Raph
  • 为某个时刻添加持续时间 (moment.js)

    时刻版本 2 0 0 阅读文档后 http momentjs com docs manipulating add 我认为这很简单 Chrome 控制台 var timestring1 2013 05 09T00 00 00Z var tim
  • 使用nodejs的sequelize更新多对多连接表

    我有一个产品表和一个类别表 一个产品可以有多个类别 一个类别可以有多个产品 因此我有一个 ProductsCategories 表来处理多对多连接 在下面的示例中 我尝试将我的一款产品 ID 为 1 与 3 个不同的类别 ID 为 1 2
  • document.write 在同一页面上显示内容。

    我对 javascript document write 方法有疑问 大多数情况下 当我使用 document write 时 它会向我显示在不同页面中使用该方法编写的内容 例如 如果我写这样的命令 document write Hello
  • NodeJS - 将相对路径转换为绝对路径

    In my 文件系统我的工作目录在这里 C temp a b c d 在 b bb 下有文件 tmp txt C temp a b bb tmp txt 如果我想从工作目录转到该文件 我将使用以下路径 bb tmp txt 如果该文件不存在
  • iPhone 上的锁定方向 UIWebView

    有没有办法锁定 UIWebView 的方向 使用 Obj C JS 还是 Html 我不想有按钮或任何东西 我只想在应用程序打开时将其锁定为纵向 好像这个堆栈溢出帖子 https stackoverflow com questions 43
  • 即使我的情况按预期发生变化,Angular ngClass 也不会更新我的课程

    我正在创建的模板中有类似的内容 div class nng 3 div 价值app layout isNavbarFixed等用零或一初始化 并且页面第一次加载时 适当的类被插入到我的div 不过 此后通
  • 在 Express.js 中使用相同的响应对象发送多个响应(res.json)

    res json Object assign cart generateArray res json JSON stringify cart totalPrice 我如何发送发送多个响应 因为我的代码不起作用 谢谢 您不能发送多个回复 您发
  • 当rest api应用程序服务器(express)和Angulars js应用程序在不同端口上运行时出现Cors问题

    我有用node js编写的rest api应用程序 express在端口3000上运行 而angularjs应用程序在同一服务器上的端口9001上运行 从 angularjs 应用程序调用 rst api 时 出现了 cors 问题 在re
  • 从浏览器访问本地文件?

    您好 我想从浏览器访问系统的本地文件 由于涉及大量安全检查 是否可以通过某种方式实现这一目标 或使用 ActiveX 或 Java Applet 的任何其他工作环境 请帮帮我 要通过浏览器访问本地文件 您可以使用签名的 Java Apple
  • jQuery:向左滑动和向右滑动

    我见过slideUp and slideDown在 jQuery 中 左右滑动的功能 方式怎么样 您可以使用 jQuery UI 中的附加效果来做到这一点 详情请参阅此处 http docs jquery com UI Effects Sl
  • 如何告诉node.js mysql没有在默认端口上运行?

    我遇到了与此人类似的问题 连接 ECONNREFUSED 节点 js sql https stackoverflow com questions 8825342 connect econnrefused node js sql 我正在尝试将
  • jQuery UI 对话框 - 关闭后无法打开

    我有一个问题jquery ui dialog box https jqueryui com dialog 问题是 当我关闭对话框然后单击触发它的链接时 除非刷新页面 否则它不会再次弹出 如何在不刷新实际页面的情况下回调对话框 下面是我的代码
  • 如何得知客户端从服务器的下载速度?

    根据客户的下载速度 我想以低质量或高质量显示视频 任何 Javascript 或 C 解决方案都是可以接受的 Thanks 没有任何办法可以确定 您只能测量向客户端发送数据的速度 如果没有来自客户端的任何类型的输入来表明其获取信息的速度 您
  • 从json中获取所有子节点

    我有以下 json var source k 01 k 02 children k 05 k 06 children k ABC k PQR k 07 k 03 我希望能够指定 k 的值并取回所有孩子 以及孙
  • 如何强制下载图片?

    我的页面上有一个动态生成的图像 如下所示 img src 我不想告诉我的用户右键单击图像并点击保存 而是想公开一个下载链接 单击该链接将提示下载图像 如何实现这一目标 最初我在 js 中尝试这样做 var path my image att
  • 拉斐尔路径交叉点不起作用

    我对拉斐尔和 pathIntersection method JSFiddle 示例 http jsfiddle net t6gWt 2 您可以看到有两条线都与曲线相交 但当我使用 pathIntersection method 有一个未解

随机推荐

  • 如何在 ASP.NET WebAPI 中返回文件 (FileContentResult)

    在常规 MVC 控制器中 我们可以使用以下命令输出 pdfFileContentResult public FileContentResult Test TestViewModel vm var stream new MemoryStrea
  • Node.js、protobuf、buffer.length..如何通过 tcp 发送结构化缓冲区/消息?

    我写了一个 node ssjs 程序 它可以 使用 TLS 模块与数据服务器 Apache MIMA 进行 TCP 连接 好的 通过 protobuffer 模块对消息进行编码 解码 序列化 反序列化 OK 将序列化消息发送到服务器并获取响
  • 默认插入向量不是默认初始化吗?

    中的一个std vector构造函数规定为 强调我的 explicit vector size type n const Allocator Allocator Effects 构造一个vector with n 默认插入使用指定分配器的元
  • 如何在组框中获取选中的单选按钮? [复制]

    这个问题在这里已经有答案了 我的组框中有很多单选按钮 通常我会使用单独检查每个单选按钮If radiobutton1 Checked True Then 但我认为也许有一种聪明的方法来检查组框中正在检查哪个单选按钮 任何想法 try thi
  • 从 sqlite 数据库中获取最后一行

    我正在尝试从 SQLite 数据库中获取最后一行 到目前为止 我已经尝试过 max sql sequence 但似乎没有任何效果 我必须获取行值并将其分配给类变量 由于我是 SQLite 和 Android 的新手 因此非常感谢任何帮助 谢
  • 使用自定义引导加载程序创建可引导 ISO 映像

    我正在尝试将我用汇编语言编写的引导加载程序转换为ISO图像文件 以下是代码来自MikeOS http mikeos sourceforge net write your own os html引导加载程序 这是我的引导加载程序代码 BITS
  • 在 C# 中创建不同的画笔图案

    我正在尝试做一些类似于绘画的东西 我想弄清楚如何制作不同的画笔样式 就像在 Paint 3D 中一样 使用钢笔工具与使用画笔工具时 您会得到一定的线条填充 我不知道从哪里开始 我一天中的大部分时间都在浏览文档并观看 YouTube 视频 我
  • DataTable服务器端处理添加编辑列

    我正在使用数据表 1 10 13 服务器端处理 我想添加一个带有编辑用户链接的 编辑 列 这个怎么做 我的js文件 userTable DataTable processing true serverSide true ajax type
  • 如何将Imageview放在其他布局后面

    我使用图像视图进行动画 这样它看起来就像从左到右的移动 但我的图像显示在其他视图的前面 以便用户能够单击图像 我正在尝试显示它behind另一种观点
  • 从 ROC 曲线获取阈值

    我有一些模型 使用ROCR将预测类百分比向量封装起来 我有一个性能对象 使用规格 tpr fpr 绘制性能对象可以得到一条 ROC 曲线 我正在比较特定误报率阈值 x 的模型 我希望从性能对象中获取真阳性率 y 的值 更重要的是 我想获得用
  • 在 ssh 模式下运行时在 vscode 中打开本地终端

    当我通过 ssh 连接到 vscode 中的远程计算机时 集成终端会在远程计算机中打开一个终端 有没有办法用本地计算机的终端打开终端面板 Using the command palette default ctrl shift p cmd
  • ASP.NET 成员资格保持身份验证问题

    因此 我的应用程序很奇怪 因为当您登录时 您将保持登录状态一两页 然后就迷路了 我的设置是这样的
  • C99 支持真的还没有广泛普及吗?

    我正在阅读 GNOME 项目的一些最佳实践 他们一直强调的一件事是避免 C99 功能 因为支持仍然不广泛 他们提到的一些功能包括单行注释和在块中间声明变量等功能 这让我想知道 C99 是否支持 即使是像这样的基本功能 评论 真的还没有广泛传
  • 如何在 JAVA 中使用 PDFBox 从 PDF 创建图像

    我想从 PDF 的第一页创建图像 我正在使用 PDFBox 在网上研究后 我发现了以下代码片段 public class ExtractImages public static void main String args ExtractIm
  • libpthread.so.0:添加符号时出错:命令行中缺少 DSO

    当我编译 openvswitch 1 5 0 时 遇到以下编译错误 gcc Wstrict prototypes Wall Wno sign compare Wpointer arith Wdeclaration after stateme
  • 从监听器访问对象

    假设我们有一些Foo包含的类 public void setOnSomethingListener OnSomethingListener listener 我们将其注册为 Foo foo new Foo foo setOnSomethin
  • 如何公开嵌入式 Flash 对象的 JavaScript 接口?

    JavaScript 和Flash Player 可以通过Flash 的ExternalInterface 机制交换数据 您注册希望能够从JavaScript 调用的ActionScript 函数 我的问题 如何找出 Flash 对象的哪些
  • Python:为什么我收到 AttributeError:__enter__

    我没有重新分配 open 关键字 但仍然收到此错误 有任何建议或方向来修复我的错误吗 with tempfile mkdtemp as test dir print test dir AttributeError enter 我也是Pyth
  • 只有变量可以通过引用传递 - php

    我正在尝试此代码 但出现此错误 Only variables can be passed by reference in xxx script class page function insert db of form arr i 0 fo
  • 如何用 Jest 模拟 Axios?

    我有一个函数client index js这是使用 axios 发出请求 import axios from axios const createRequest async url method gt const response awai