全局 Jest SpyOn 函数不调用原始函数

2023-12-20

我希望有人能帮助我理解 js 原型的交互性和jest.spOn().

我有一个小例子: 文件中的示例类TestObj.ts:

export default class TestObj {
  foo() {
    // Do Something e.g.
    console.log("Hello World!");
  }
}

以下示例测试用例成功,但console.log永远不会被执行。

import TestObj from './TestObj';

const spyObj = jest.spyOn(TestObj.prototype, 'foo');
test('debug test', () => {
  const obj = new TestObj();
  obj.foo();
  expect(spyObj).toHaveBeenCalled();
});

如果我将示例测试用例更改为以下内容,则测试成功并且console.log语句按预期被调用。

import TestObj from './TestObj';

test('debug test', () => {
  const spyObj = jest.spyOn(TestObj.prototype, 'foo');
  const obj = new TestObj();
  obj.foo();
  expect(spyObj).toHaveBeenCalled();
});

知道为什么使用全局间谍变量的版本不能按预期工作吗?


Edit:

它似乎与原型无关。 对于没有任何类的函数也存在同样的问题, 编辑第一个代码片段(TestObj.ts)对此:

export foo() {
  // Do Something e.g.
  console.log("Hello World!");
};

我们在更新的第二个截图中收到了同样的问题。 (测试成功,但从未到达控制台日志。)

import * as testlib from './TestObj';

const spyObj = jest.spyOn(testlib, 'foo');
test('debug test', () => {
  testlib.foo();
  expect(spyObj).toHaveBeenCalled();
});

但是,如果我们将第二个代码片段更新为以下内容,则测试会成功并执行控制台日志:

import * as testlib from './TestObj';

const spyObj: jest.SpyInstance;

beforeEach(() => {
  spyObj = jest.spyOn(testlib, 'foo');
});
test('debug test', () => {
  testlib.foo();
  expect(spyObj).toHaveBeenCalled();
});

但是我仍然不知道为什么会发现这个问题。


谁遇到过这篇文章,

问题解释

我做了很多研究(try&error、mdn、jest manpage 和很多媒体文章),我想我找到了奇怪行为的原因。要理解这个问题,了解以下几点很重要:

  • 1:JS原型是全局变量,每个对应类型的对象都依赖。
  • 2:Jest 不会在每次测试后重置全局变量,之前或在任何测试中对全局变量所做的更改将保留在整个测试套件(文件)中。
  • 3:笑话监视函数实际上是指定函数的模型,并有一个调用该函数本身的实现。例如。:jest.SpyOn(TestObj.prototype, 'foo');实际上是实现为:TestObj.prototype.foo = new jest.fn().mockImplementation(()=>{original_TestObj.prototype.foo()});这意味着监视类原型的函数实际上是在更改全局变量。
  • 4:根据您的笑话配置,可以在每次测试之前将模型函数重置为默认值。但要小心默认函数spyOn似乎与相同jest.fn()它本身是一个空实现,这意味着模型仍然可以调用,但没有代码,尤其是原始实现不被执行。

Solution

  • 如果您希望测试用例彼此独立,请避免更改全局变量。
  • 在测试用例中,避免监视原型,如果您仅在单个测试中需要监视,请尝试监视本地对象,例如:
test('should foo', () => {
  const testObj = new TestObj();
  const spyOnFn = jest.spyOn(testObj, 'foo');

  // Do anything 

  expect(spyOnFn).to//Have been anything
});
  • 如果需要spyOn相同功能的实现 在多个测试中尝试为测试创建一个全局变量 但使用 jest 的 before every 功能来设置 Spy。这 功能在所有模拟重置后执行(如果启用)。 例如。:
let spyOnFunction1: jest.SpyInstance;

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

全局 Jest SpyOn 函数不调用原始函数 的相关文章

  • 在 contenteditable div 中选择范围

    我有一个contenteditablediv 和其中的一些段落 这是我的代码 div style border solid 1px black width 300px height 300px div Hello world div div
  • JavaScript 中的埃拉托斯特尼筛法对大量数据无限运行

    我一直在尝试写埃拉托斯特尼筛法 http en wikipedia org wiki Sieve of EratosthenesJavaScript 中的算法 基本上我只是按照以下步骤操作 创建从 2 到 n 1 的连续整数列表 令第一个素
  • 为什么我的淘汰单选按钮在另一个具有点击绑定的元素内时会失败?

    我有一个单选按钮列表 我想要点击 li 他们还检查单选按钮 这一切都有效 直到我放了一个name单选元素上的属性 然后我的代码停止工作 我的代码如下所示 ul li li ul li
  • 带有淘汰赛js的隐形recaptcha

    我正在完成隐形验证码 但我在实现它时遇到问题 谷歌开发人员页面中的代码显示它应该是这样的
  • 防止 iOS 键盘在 cordova 3.5 中滚动页面

    我正在使用 Cordova 3 5 和 jQuery mobile 构建 iOS 应用程序 我在大部分应用程序中禁用了滚动功能 但是 当我选择输入字段时 iOS 键盘会打开并向上滚动页面 我不想要这个功能 由于输入足够高 键盘不会覆盖它 我
  • 设置 cookie 时中断 JavaScript 执行

    当设置 cookie 时 是否可以始终中断浏览器开发人员工具中的 javascript 执行 无需显式设置 JS 断点 document cookie 在 html head 块的开头添加此代码片段效果很好
  • 尝试将数据存储在点击器网站中

    我正在尝试存储一个名为的变量score无论何时刷新 您都会一次又一次地使用它 我不明白的是它的代码是什么 我尝试了一些方法 但似乎都不起作用 这是我的答题器网站 但是当我尝试使用 JavaScript 来存储它时 它不起作用window o
  • 刷新页面时保存用户的选择

    我目前有一个页面显示不同团队的数据 我有一些数据 用户可以单击使其处于 打开 或 关闭 状态 并为每个数据显示不同的图标 它基本上就像一个清单 只是没有物理复选框 我想记住哪些 复选框 已被选中 即使在用户刷新页面或关闭浏览器并稍后返回之后
  • 将 UMD Javascript 模块导入浏览器

    你好 我正在对 RxJS 进行一些研究 我可以通过在浏览器中引用它来使用该库 如下所示 它使用全局对象命名空间变量 Rx 导入 我可以制作可观察的东西并做所有有趣的事情 当我将 src 更改为指向最新的 UMD 文件时 一切都会崩溃 如下所
  • Firebase 函数 onWrite 未被调用

    我正在尝试使用 Firebase 函数实现一个触发器 该触发器会复制数据库中的一些数据 我想观看所有添加的内容votes user vote 结构为 我尝试的代码是 const functions require firebase func
  • 从数据库检查数据的异步解决方案各种循环子句

    我想要做的是异步检查数据库并从中获取结果 在我的应用程序中我试图实现Asynchronously将此步骤解决为 从数据库中检查手机号码JsonArray循环子句的种类 Create JsonArray从结果 打印创建的数组 我学到了足够多的
  • 使用 Vue 的多模式组件

    我在 Vue 中实现动态模式组件时遇到问题 A common approach I follow to display a set of data fetched from the db is I dump each of the rows
  • CSF3 中的 Typescript 支持

    我正在使用 CSF3 编写故事 并且我想正确注释我的故事 我用谷歌搜索过 基本上找不到答案 我尝试过一些技巧here https github com storybookjs storybook issues 7677但没有任何效果 我发现
  • 在 Shopify 商店中嵌入 Vue 组件

    在产品页面中 我尝试显示自定义 Vue 组件 为简洁起见 该组件根据给定的产品 ID 显示 Firebase 数据库中的一些信息 我最初尝试将其制作为 Shopify 应用程序 以便我可以访问他们的 API 我实现了 OAuth 并且可以检
  • 带参数的事件监听器

    我想将参数传递给 JavaScript 中的事件侦听器 我已经找到了解决方案 但我无法理解它们为什么或如何工作以及为什么其他解决方案不起作用 我有 C C 背景 但是 Javascript 函数的执行有很大不同 您能否帮助我理解以下示例如何
  • 使用 Vite 和 React 进行生产构建时出错:Uncaught TypeError 中的错误:_ 不是函数

    我在我的网站上使用 Vite React React Router 和 TypeScript 我在运行生产构建时遇到问题 在开发模式下一切正常 使用生产版本时 我的浏览器显示白色背景 并且在浏览器控制台中出现以下错误 上面的链接将我带到第
  • Javascript Replace() 和 $1 问题

    我正在尝试创建一个脚本来搜索文本中的模式并在它找到的字符串周围包裹一个标签 shop attributes td each function this html function i html return html replace E 0
  • 从 FileReader 设置背景图像样式

    我正在寻找一种解决方案 允许我从文件上传输入中获取文件并通过设置 document body style backgroundImage 来预览它 以下代码用于在 Image 元素中显示预览 function setImage id tar
  • 如何使用 Angular CLI 在特定文件夹中生成组件?

    我将 Angular 4 与 Angular CLI 结合使用 并且可以使用以下命令创建一个新组件 E HiddenWords gt ng generate component plainsight 但我需要在 plainsight 中生成
  • 如何使用asm.js进行测试和开发?

    最近我读到asm js规范 看起来很酷 但是是否有任何环境 工具来开发和测试这个工具 这还只是处于规范阶段吗 您可以尝试使用 emscripten 和 ASM JS 1 并从侧分支在 firefox 构建中运行它 有关 asm js 的链接

随机推荐

  • 在 .Net (C#) 中构建 Google 产品 Feed?

    以下是我试图遵循的架构
  • 带返回值的 Powershell 递归

    我正在尝试编写一个递归函数 它将返回数组中的信息 但是当我将 return 语句放入函数中时 它会丢失某些条目 我试图递归地查看指定深度的文件夹 获取与该文件夹关联的 acl 我知道 getChildItem 有一个递归选项 但我只想单步执
  • 将单个文件卷安装为 Docker 中的目录

    Docker 文档 http docs docker com engine userguide dockervolumes mount a host file as a data volume说可以将单个文件挂载到 Docker 容器中 v
  • 玩! 2.0 Scala - 访问全局对象

    我已经声明了一个在应用程序启动时实例化的对象 我想在控制器内访问它 这是插件的一部分 我希望能够使用该插件 但我似乎无法通过第一部分 找到MyWebsocketConnection目的 没有一个示例显示如何执行此操作 我不想注入控制器 因为
  • 如何修复 Prisma Client 自定义模型未定义的问题

    我生成了一个项目打字稿快速启动器 https www npmjs com package typescript express starter并选择了Prisma https www prisma io 作为 ORM 启动项目生成的基本 用
  • python:对我的复制变量的更改会影响原始变量[重复]

    这个问题在这里已经有答案了 我有一个列表 我创建了一个副本 以便在保留原始列表的同时进行一些操作 然而 当我设置copy list等于org list 它们会变成同样的东西 如果我改变copy list org list也发生变化 例如 o
  • Flutter 视频播放器无法在 ios 中播放

    我正在使用 video player 包在 flutter 中播放网络视频 在安卓上运行良好 但在ios上无法加载 颤振3 3 3 视频播放器 2 4 7 PS 服务器调用是https 问题发生在真实设备和响应头有接受范围 字节 Reque
  • 无法在 MySQL 5.7 中添加外键(引用表中缺少约束)

    我正在尝试运行外键添加查询 如下所示 外键检查设置为 0 两个表中的列完全相同 此外 两者都是主键 这里的解决方案都没有帮助解决这个问题 我在本地主机上 mysql gt alter table deliveryaddress gt add
  • 如何从 b 树中删除元素?

    我正在尝试了解 b 树 我能找到的每个来源似乎都忽略了有关如何从树中删除元素同时保留 b 树属性的讨论 有人可以解释该算法或向我指出可以解释其工作原理的资源吗 维基百科页面上有对此的解释 B 树 删除 http en wikipedia o
  • 在发生未处理的异常后,我可以将执行返回到失败的方法吗?

    我有一个 ASP NET 网站 其中包含一些 WCF 服务 我已连接到 Application Error 事件 因此可以记录任何未处理的异常 我真正想做的是将执行传递回被调用的方法 这样我就可以向客户端返回一些有意义的内容 而不是抛出Fa
  • 将按结果分组保存到单独的 CSV 文件中

    我有一个代码 用于使用 CSV 数据创建组并使用该组创建新文件 我读取了 csv 文件 然后使用它 问题是当我的函数工作并使用数据创建新文件时 新文件的名称是组的名称 我不希望这样 ID Inventory Domain Requests
  • Android从缩略图获取图像路径?

    我正在尝试为目前市场上的我的应用程序提供关键更新 我需要查询 MediaStore 中的缩略图 并将缩略图加载到 GridView 中 到目前为止一切顺利 现在我只需要根据我所拥有的内容 即缩略图的路径 获取用户外部存储上实际全尺寸图像的路
  • Oracle复制数据到另一个表

    在Oracle中 我将数据从备份复制到新表 但不起作用 正确的语法是什么 Thanks select CODE MESSAGE into EXCEPTION CODES CODE MESSAGE from Exception code tm
  • 为什么 sizeof(std::mutex)==40 (gcc,clang,icc)? [复制]

    这个问题在这里已经有答案了 而不是sizeof std atomic
  • 使用 SvelteKit 将图像放置在哪里

    我已经使用 Svelte 一段时间了 现在我已切换到 SvelteKit 这样我就可以添加多个页面 我想向我的网站添加一些图像 但我不知道将它们放在哪里 在 Svelte 中我会把它们放进去public images但没有public带有
  • 在 Android 上的 AAC 流中查找

    我从 HTTP 服务器获取 AAC 流并将其用作MediaPlayer在安卓中 它运行得很好 但是当我尝试执行时mediaPlayer seekTo int position 我收到以下错误大约一百万次 WARN AACDecoder 13
  • 处理 PowerShell 脚本中的命令提示符错误

    我正在尝试运行一些命令提示符命令 例如schtasks在 PowerShell 脚本中 我想知道如何处理 PowerShell 中命令引发的错误 I tried cmd exe c schtasks Query TN xx echo ERR
  • System.Messaging - 为什么 MessageQueue 不提供 Send 的异步版本

    有人知道为什么 System Messaging 不提供异步版本的 Send 方法来将 MSMQ 消息发送到队列 实际上有 Peek 和 Receive 方法的异步版本 通过可以转换为 C 5 异步等待方法的 Begin End 对 但令人
  • 初始化一个sqlite数据库android

    大家好 我对 Android 开发还很陌生 我想向我的应用程序添加一个数据库 问题是我不知道如何仅初始化整个表一次 我读了很多书 发现你可以做到 的压倒性作用onCreate SQLiteDatabase db 辅助类中的方法 这些是我的数
  • 全局 Jest SpyOn 函数不调用原始函数

    我希望有人能帮助我理解 js 原型的交互性和jest spOn 我有一个小例子 文件中的示例类TestObj ts export default class TestObj foo Do Something e g console log