使用 Jest 模拟 Es6 类

2024-04-25

我正在尝试使用接收参数的构造函数来模拟 ES6 类,然后使用 Jest 模拟该类上的不同类函数以继续测试。

问题是我找不到任何有关如何解决此问题的文档。我已经看过了这个帖子 https://stackoverflow.com/questions/43749845/how-to-mock-es6-class-using-jest,但它并没有解决我的问题,因为实际上OP甚至不需要模拟类!该帖子中的另一个答案也根本没有详细说明,没有指向任何在线文档,也不会导致可复制的知识,因为它只是一个代码块。

假设我有以下课程:

//socket.js;

module.exports = class Socket extends EventEmitter {

    constructor(id, password) {
        super();

        this.id = id;
        this.password = password;

        this.state = constants.socket.INITIALIZING;
    }

    connect() {
        // Well this connects and so on...
    } 

};

//__tests__/socket.js

jest.mock('./../socket');
const Socket = require('./../socket');
const socket = new Socket(1, 'password');

expect(Socket).toHaveBeenCalledTimes(1);

socket.connect()
expect(Socket.mock.calls[0][1]).toBe(1);
expect(Socket.mock.calls[0][2]).toBe('password');

很明显,我试图嘲笑的方式Socket和类函数connect这是错误的,但我找不到正确的方法。

请在你的答案中解释你模拟这个的逻辑步骤以及为什么每个步骤都是必要的+如果可能的话提供 Jest 官方文档的外部链接!

谢谢您的帮助!


Update:

所有这些信息和更多信息现已添加到新指南中的 Jest 文档中,“ES6 类模拟 https://facebook.github.io/jest/docs/en/es6-class-mocks.html."

完全披露:我写的。 :-)


模拟 ES6 类的关键是要知道ES6 类是一个函数。所以,模拟也必须是一个函数.

  1. Call jest.mock('./mocked-class.js');,并导入“./mocked-class.js”。
  2. 对于要跟踪调用的任何类方法,创建一个指向模拟函数的变量,如下所示:const mockedMethod = jest.fn();。在下一步中使用它们。
  3. Call MockedClass.mockImplementation()。传入一个箭头函数,该函数返回一个包含任何模拟方法的对象,每个方法设置为自己的模拟函数(在步骤 2 中创建)。
  4. 可以使用手动模拟(__mocks__ 文件夹)来模拟 ES6 类来完成同样的事情。在这种情况下,导出的模拟是通过调用创建的jest.fn().mockImplementation(),与上面 (3) 中描述的参数相同。这将创建一个模拟函数。在这种情况下,您还需要导出您想要监视的任何模拟方法。
  5. 可以通过调用来完成同样的事情jest.mock('mocked-class.js', factoryFunction),其中,factoryFunction 又是上面 3 和 4 中传递的相同参数。

一个例子抵得上一千个字,所以这里是代码。 此外,这里还有一个演示所有这些的存储库:https://github.com/jonathan-stone/jest-es6-classes-demo/tree/mocks-working https://github.com/jonathan-stone/jest-es6-classes-demo/tree/mocks-working

首先,对于你的代码

如果您要添加以下设置代码,您的测试应该会通过:

const connectMock = jest.fn(); // Lets you check if `connect()` was called, if you want

Socket.mockImplementation(() => {
    return {
      connect: connectMock
    };
  });

(注意,在您的代码中:Socket.mock.calls[0][1]应该[0][0], and [0][2]应该[0][1]. )

接下来,一个人为的例子

内嵌一些解释。

模拟类.js。请注意,测试期间永远不会调用此代码。

export default class MockedClass {
  constructor() {
    console.log('Constructed');
  }

  mockedMethod() {
    console.log('Called mockedMethod');
  }
}

模拟类consumer.js。此类使用模拟类创建一个对象。我们希望它创建一个模拟版本而不是真实版本。

import MockedClass from './mocked-class';

export default class MockedClassConsumer {
  constructor() {
    this.mockedClassInstance = new MockedClass('yo');
    this.mockedClassInstance.mockedMethod('bro');
  }
}

模拟类consumer.test.js- 考试:

import MockedClassConsumer from './mocked-class-consumer';
import MockedClass from './mocked-class';

jest.mock('./mocked-class'); // Mocks the function that creates the class; replaces it with a function that returns undefined.

// console.log(MockedClass()); // logs 'undefined'

let mockedClassConsumer;
const mockedMethodImpl = jest.fn();

beforeAll(() => {
  MockedClass.mockImplementation(() => {
    // Replace the class-creation method with this mock version.
    return {
      mockedMethod: mockedMethodImpl // Populate the method with a reference to a mock created with jest.fn().
    };
  });
});

beforeEach(() => {
  MockedClass.mockClear();
  mockedMethodImpl.mockClear();
});

it('The MockedClassConsumer instance can be created', () => {
  const mockedClassConsumer = new MockedClassConsumer();
  // console.log(MockedClass()); // logs a jest-created object with a mockedMethod: property, because the mockImplementation has been set now.
  expect(mockedClassConsumer).toBeTruthy();
});

it('We can check if the consumer called the class constructor', () => {
  expect(MockedClass).not.toHaveBeenCalled(); // Ensure our mockClear() is clearing out previous calls to the constructor
  const mockedClassConsumer = new MockedClassConsumer();
  expect(MockedClass).toHaveBeenCalled(); // Constructor has been called
  expect(MockedClass.mock.calls[0][0]).toEqual('yo'); // ... with the string 'yo'
});

it('We can check if the consumer called a method on the class instance', () => {
  const mockedClassConsumer = new MockedClassConsumer();
  expect(mockedMethodImpl).toHaveBeenCalledWith('bro'); 
// Checking for method call using the stored reference to the mock function
// It would be nice if there were a way to do this directly from MockedClass.mock
});
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Jest 模拟 Es6 类 的相关文章

  • 如何将node.js管道传输到redis?

    我有很多数据要插入 SET INCR 到redis DB 所以我正在寻找pipeline http redis io topics pipelining 质量插入 http redis io topics mass insert通过node
  • 如何使用 ASP.Net 中的 PageMethods 将多维数组从 Javascript 传递到服务器

    我有一些 li 我的 HTML 页面中的项目如下 li li class ui state default Item 2 li li class ui state default Item 3 li li class ui state de
  • 找出右键单击的 DOM 元素

    我使用以下代码片段来构建自定义上下文菜单
  • Chart.JS 工具提示回调标签和标题 (v3.5)

    请注意 v2 有很多答案 这是 v3 的 我正在尝试设置工具提示label and title对于圆环图 Code Create the donut chart donut new Chart questions positivity do
  • Iron 路由器中的多个订阅

    我一直在开发一个使用评论功能的应用程序 这导致必须订阅发表评论的集合和评论集合本身 现在看起来像这样
  • 如何在 Angular 4 材料的 Stepper 中提交表单

    如何在角材料的步进器中提交表单数据 我正在遵循角材料的示例https material angular io components stepper examples https material angular io components
  • 为响应中的特定槽位提供槽位值并恢复对话

    我正在处理 lex 并希望在响应中给出槽值 只有当用户在前一个槽值中输入特定输入时才会询问该值 我正在尝试一些事情 但我不这样做 我做得对还是错 我在 lex 中有以下插槽 出发城市 到达城市 出发 单程或往返 归期 日期 出发日期 航班时
  • 如何使用 Jasmine 监视 AngularJS 的 $timeout?

    我试图监视 timeout 以便我可以验证它是否未被调用 具体来说 我的生产代码 见下文 将 timeout 作为函数调用 而不是对象 timeout function and not timeout cancel for instance
  • IE 抛出 JavaScript TypeError 但在 chrome 上不抛出

    描述在我们的 Magento 购物车上 当用户单击添加到购物篮在任何 Internet Explorer 浏览器的 产品详细信息 页面上单击按钮 浏览器中都会弹出一个包含以下错误消息的窗口 异常 类型错误 无法获取未定义或空引用的属性 ta
  • 如何使用 JS 和 Chrome 控制台向频道发送 Discord 消息?

    如何使用 JS 和 Chrome 控制台在不使用 Discord API 的情况下将 Discord 消息发送到 Discord 频道 看来这是不可能的事了 打开不和谐控制台 ctrl shift i 不起作用 请参阅下面的编辑 然后进入网
  • Redux 中的排队操作

    我目前遇到的情况是我需要连续运行 Redux Actions 我看过各种中间件 比如 redux promise 看起来不错如果您知道触发根操作 由于缺乏更好的术语 时的连续操作是什么 本质上 我想维护一个可以随时添加的操作队列 每个对象在
  • 如何让 ckeditor 停止删除空 div

    stackoverflow 上也有类似的问题 但这些问题的答案对我不起作用 所以请不要将其标记为重复 在我的 cms 中 我希望人们能够添加 SPA 单页应用程序 内容页面 此类应用程序通常只有一个具有某些属性的 div 并且使用 java
  • 如何通过 Grunt 运行节点脚本?

    我希望通过我的 gruntfile 运行节点命令 我只需要运行 node index js 作为任何其他任务之前的第一个任务 我尝试四处寻找但没有找到答案 我相信这可能很简单 但我不确定如何做 我需要加载 nmp 任务吗 这就是我的 Gru
  • PapaParse 与 Angular JS

    喜欢 PapaParse 漂亮的 CSV 解析器和解解析器 任何人都可以帮助我将其与 Angular JS 结合起来吗 我喜欢让 PapaParse 以 Angular 方式工作 正在尝试解决方案 实际上我没有做任何花哨的事情来加载它 只需
  • es6 import var 未在代码导入中定义

    出于某种原因 当我执行 var sphere new Core 时在游戏中 我看到核心未定义 即使我导入它 Game js import Core from gameUnits Core export class Game construc
  • 0x800a138f - JavaScript 运行时错误:无法获取未定义或 null 引用的属性“值”

    我编写了一段 JavaScript 代码来比较 2 个文本框中的 2 个日期 function CompareDates var fdate document getElementById txtFromDate var edate doc
  • 智能表 - 预选特定行

    我正在使用智能表 我需要预先选择特定行 因此 在加载我的列表后 我循环进入它并设置isSelected当我到达我想要选择的项目时属性 Preselect a row for var i 0 len scope displayCollecti
  • 如何使用ajax从服务器接收返回的数据?

    基本上我有一个带有用户名文本框和提交按钮的表单 现在我想要的是 当用户在文本框中输入文本时 它应该获取文本框值并将用户名发送到服务器 以便服务器可以检查该用户名是否被任何其他用户占用 我可以将文本值发送到服务器 但我不知道如何接收回一些数据
  • 如何从 Backbone 集合中提取多个属性?

    我试图从 Backbone 集合中提取多个属性 但它返回undefined 收藏 id 1 name raju age 23 sex male hobbies id 2 name ramesh age 43 sex male hobbies
  • 如何获取firestore集合下的文档数量? [复制]

    这个问题在这里已经有答案了 我想获取 firestore 集合中的文档总数 我正在制作一个论坛应用程序 所以我想显示每个讨论中当前的评论量 有类似的东西db collection comments get lenght或类似的东西 随着si

随机推荐

  • Eclipse(在 Ubuntu 上)没有 jsp、html 和其他 Web 文件模板

    我使用 Synaptic Package Manager Ubuntu 9 10 安装了 Eclipse 但是 我的 Eclipse 没有任何 HTML 模板 在 新建 对话框中 或 JSP 模板 我该如何修复它 以便我在那里拥有一些 HT
  • Python根据for循环索引创建变量[重复]

    这个问题在这里已经有答案了 我正在尝试为 for 循环的每次迭代创建变量 对于范围 10 内的 i x i abc 这样我就可以得到 x1 x2 x3 x4 x10 都等于 abc 有人知道该怎么做吗 谢谢 你不应该这样做 将你的值存储在d
  • 使用 Base64 和 JSON 上传大图像

    我正在使用此功能将图像上传到服务器JSON 为此 我首先将图像转换为NSData然后到NSString using Base64 当图像不是很大时 该方法工作正常 但当我尝试上传 2Mb 图像时 它会崩溃 问题是服务器没有收到我的图像 即使
  • 使用 Appcompat v7 的抽屉式导航 - ?android:attr 标签的问题

    我在我的项目中使用操作栏和导航抽屉 使用 appcompat v7 和 v4 我已经添加了 appcompat v7 和资源 以下是我的导航抽屉列表的文本视图 直接取自位于以下位置的 Android 示例应用程序 创建抽屉式导航 http
  • C#:通过反射检索和使用 IntPtr*

    我目前正在编写一些代码 这些代码反映了从调用本机 dll 中编组回来的结构 某些结构包含指向以 null 结尾的指针数组的 IntPtr 字段 这些领域需要特殊处理 当反映结构时 我可以识别这些字段 因为它们是由自定义属性标记的 以下说明了
  • ant-找不到符号@Test

    我正在尝试编译以下仅包含一个函数的类 公共类测试注释 Test public void testLogin System out println Testing Login 当我将文件作为 JUNIt 运行时 它可以工作 但是当我尝试从 b
  • 计算 a*a mod n 且不溢出

    I need to calculate a a mod n but a is fairly large resulting in overflow when I square it Doing a n a n n doesn t work
  • 树莓派蓝牙4.0连接

    我正在尝试使用 CoreBluetooth 蓝牙 4 0 通过 iPhone 连接到 Raspberry Pi 我已经发现了该设备并使用以下代码发出连接请求 if peripheral self foundPeripheral NSLog
  • Javascript ResizeObserver 意外触发

    Why the ResizeObserver类总是首先执行处理程序observe 尝试在 Chrome 开发工具上执行以下代码 new ResizeObserver gt console log resize detected observ
  • 从 asp.net 中的 dataSet 获取单个值

    我正在执行查询以从 tbl message 表获取 Title 和 RespondBY 我想在对转发器进行数据绑定之前解密标题 在进行数据绑定之前如何访问标题值 string MysqlStatement SELECT Title Resp
  • jQuery 显示/隐藏/切换有效,但没有保持应有的状态 - 它恢复到原始状态

    我尝试使用 jQuery 显示 隐藏常见问题解答 这个想法是列出所有问题 只有当用户想要查看答案时 他们才会单击问题 看起来像链接 然后答案就会变得可见 它有点有效 只不过一旦单击答案就会恢复到其原始状态 在这种情况下 这意味着当我单击问题
  • 对一列进行唯一约束,排除其他列中具有相同值的行

    我想向列添加唯一键value但我必须忽略列中具有相同值的行value and header id 例如 考虑这个表 id header id value 1 1 a 2 1 a 3 2 a 因此 第 1 行和第 2 行指向同一个对象 并且唯
  • 您可以在不同的 OSGi 包中拥有 JSF 自定义组件吗?

    有人同时使用过 OSGi 和 JSF 吗 我问这个问题是因为 JSF 使用类加载器魔法来查找自定义组件 来自教程 重点是我的 这个配置文件最终会 是 META INF faces config xml 中 代表此的 jar 文件 成分 JS
  • 如何在没有 Intent 的情况下以编程方式拨打电话

    我是 Android 新手 我想在不使用intent 我知道这段代码 Intent intent new Intent Intent ACTION CALL intent setData Uri parse tel bundle getSt
  • 如何将焦点设置到重复控件内的编辑框?

    我想将焦点设置为 将光标置于重复控件中的编辑框 最后一个 重复位于面板 panelRep 内 然后我在面板外面有一个按钮 这是几乎可以工作的按钮的客户端代码 焦点已设置 字段周围的蓝色边框 但光标未放置在字段中 用户仍必须单击该字段才能写入
  • C++ 中可重用的成员函数

    我正在使用这个成员函数来获取指向对象的指针 virtual Object Create return new Object 它是虚拟的 所以我可以获得指向派生对象的指针 现在我这样做 virtual Object Create return
  • 如何在 Google Cloud Platform (GCP) 中测试 Cloud Function?

    我一直在试图寻找这个问题的答案 但无法在任何地方找到它 在 Google Cloud Platform 控制台的 Cloud Functions 部分上 有一个部分标题为 测试 但我不知道应该在此处放置什么来测试该函数 即语法 I have
  • 设计和处理闪光灯

    我正在将 Devise 3 1 1 与 Rails 3 一起使用 并且我的布局中有以下闪存处理代码 我登录我的应用程序 Flash 说 Signed in successfully 然后注销 然后错误登录并闪烁显示 Signed out s
  • iPhone:如何编写减少倒数计时器的代码?

    我想使用显示倒计时器UILabel将从 5 开始并且每秒减少 1 like 5 4 3 2 1 最后当达到 0 时隐藏标签 我尝试使用它进行编码NSTimer scheduledTimerWithTimeInterval但惨败 请帮我 我只
  • 使用 Jest 模拟 Es6 类

    我正在尝试使用接收参数的构造函数来模拟 ES6 类 然后使用 Jest 模拟该类上的不同类函数以继续测试 问题是我找不到任何有关如何解决此问题的文档 我已经看过了这个帖子 https stackoverflow com questions