使用 Jest 在 JavaScript 中测试 windowopen()

使用 jest 在 javascript 中测试 windowopen()

我最近必须为打开新浏览器窗口的 react 组件编写测试。为了打开新窗口,我在代码中使用了 window.open() 。这使得该组件易于编写,但我必须以不同的方式思考如何为此编写测试。

有关 window.open() 方法的更多信息,请参阅 mdn 网络文档。

为了设置位或背景,我有一个 react 组件,它有一个带有几个输入的简单表单。当用户完成输入并提交表单后,它会打开一个指向指定 url 的新窗口,并将输入作为 url 参数。

要测试的组件

这是该组件的一个非常简化的版本作为演示。我建议使用像react-hook-form这样的东西来为您的表单添加验证。

// myform.jsimport react, { usestate } from "react";const myform = ({ baseurl }) => {  const [name, setname] = usestate("");  const [subject, setsubject] = usestate("");  const onsubmit = () => {    window.open(      `${baseurl}?name=${encodeuricomponent(name)}&subject=${encodeuricomponent(        subject      )}`,      "_blank"    );  };  return (                 setname(e.target.value)} />             setsubject(e.target.value)}      />            );};export default myform;

现在我们有了我们的组件,让我们考虑一下对其进行测试。

立即学习“Java免费学习笔记(深入)”;

我通常会测试什么

通常我会使用断言来测试组件中渲染的内容,例如期望组件具有文本内容或断言 url 是预期的(使用 window.location.href),但我很快意识到这种方法获胜了对于这个例子来说,开玩笑是行不通的。

window.open 打开一个新的浏览器窗口,因此它不会影响我们正在测试的组件。我们无法看到新窗口内的内容或其 url 是什么,因为它超出了我们正在测试的组件的范围。

那么我们如何测试我们看不见的东西呢?我们实际上不需要测试新窗口是否打开,因为这将测试窗口界面的功能而不是我们的代码。相反,我们只需要测试 window.open 方法是否被调用。

面试猫 面试猫

AI面试助手,在线面试神器,助你轻松拿Offer

面试猫 39 查看详情 面试猫

模拟 window.open()

因此我们需要模拟 window.open() 并测试它是否在我们的代码中被调用。

// mock window.openglobal.open = jest.fn();

现在我们可以设置输入中的值,提交表单,然后测试 window.open 是否被调用。我们可以使用 fireevent 设置输入的值并按下提交按钮。

fireevent.input(screen.getbylabeltext("name"), {  target: {    value: "test name",  },});fireevent.input(screen.getbylabeltext("subject"), {  target: {    value: "an example subject",  },});fireevent.submit(  screen.getbyrole("button", { name: "submit (opens in new window)" }));

值得阅读文档以了解 fireevent 的注意事项。根据您的用例,您可能想使用用户事件。

我们想要等待该方法运行。我们可以使用 waitfor() 来做到这一点。

await waitfor(() => {  expect(global.open).tohavebeencalled();});

为了确保我们不会打开大量新窗口,我们可以检查是否只调用 window.open 一次。

await waitfor(() => {  expect(global.open).tohavebeencalledtimes(1);});

我们还可以检查调用该方法时使用的参数,传入我们期望的 url 作为第一个参数,目标作为第二个参数。

await waitfor(() => {  expect(global.open).tohavebeencalledwith(    "http://example.com?name=test%20name&subject=an%20example%20subject",    "_blank"  );});

完整的测试文件

这是完整的测试文件供您参考。

// MyForm.test.jsimport React from "react";import { fireEvent, render, screen, waitFor } from "@testing-library/react";import MyForm from "./MyForm";describe("MyForm test", () => {  beforeEach(() => {    // Mock window.open    global.open = jest.fn();  });  it("opens a new window with the correct url", async () => {    render();    fireEvent.input(screen.getByLabelText("Name"), {      target: {        value: "Test Name",      },    });    fireEvent.input(screen.getByLabelText("Subject"), {      target: {        value: "An example subject",      },    });    fireEvent.submit(      screen.getByRole("button", { name: "Submit (opens in new window)" })    );    await waitFor(() => {      expect(global.open).toHaveBeenCalled();      expect(global.open).toHaveBeenCalledTimes(1);      expect(global.open).toHaveBeenCalledWith(        "http://example.com?name=Test%20Name&subject=An%20example%20subject",        "_blank"      );    });  });});

照片由 stocksnap 上的 energepic.com

以上就是使用 Jest 在 JavaScript 中测试 windowopen()的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/390298.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月6日 15:23:54
下一篇 2025年11月6日 15:24:37

相关推荐

  • Go语言项目结构与GOPATH配置指南

    本教程详细解析Go语言的GOPATH环境变量及其在项目管理中的核心作用。我们将介绍如何正确设置和导出GOPATH,解释其与GOROOT的区别,并指导你如何根据GOPATH的约定组织项目文件,确保Go工具链能正确识别和构建你的代码,从而高效地进行Go语言开发。 Go语言开发环境的核心:GOPATH 在…

    2025年12月16日
    000
  • 使用结构体 (Struct) 替代 Map 在 Go 语言中的应用

    本文探讨了在 Go 语言中,如何使用结构体 (Struct) 替代 Map 来存储和管理结构化数据。通过将多个相关字段封装到一个结构体中,可以提高代码的可读性、类型安全性和性能。本文将通过一个具体的示例,展示如何将原本使用嵌套 Map 实现的数据结构,改用结构体来实现,并分析其优势。 在 Go 语言…

    2025年12月16日
    000
  • Go语言结构体JSON序列化:解决json.Marshal返回空对象的问题

    本文深入探讨Go语言encoding/json包在将结构体序列化为JSON时,返回空对象{}的常见问题。核心原因在于Go语言的可见性规则:只有导出的(即字段名以大写字母开头的)结构体字段才能被json.Marshal访问并序列化。教程将详细解释这一机制,提供正确的代码示例,并探讨err为何为nil以…

    2025年12月16日
    000
  • Go 语言中嵌入类型默认实现与宿主类型属性访问的最佳实践

    本文探讨 Go 语言中如何为嵌入类型提供默认方法实现,并使其能够访问宿主(嵌入者)类型的属性。Go 语言通过组合而非结构化继承实现代码复用,因此嵌入类型的方法无法直接感知其宿主类型。文章将详细介绍通过显式传递宿主实例、利用接口实现行为继承等 Go 惯用方式来解决这一问题,并提供代码示例。 引言:Go…

    2025年12月16日
    000
  • 使用牛顿法在 Go 中计算平方根:循环与函数

    本文将指导读者使用 Go 语言实现牛顿迭代法来计算平方根。我们将分析一个常见的错误,即循环条件未正确更新,导致无限循环。通过修改循环结构,确保迭代能够正常进行,最终得到精确的平方根近似值。 牛顿迭代法求平方根 牛顿迭代法是一种数值逼近方法,用于求解方程的根。在计算平方根时,我们可以将其转化为求解方程…

    2025年12月16日
    000
  • 使用Go语言与Microsoft SharePoint交互:方法与实践

    Go语言可以通过两种主要方式与Microsoft SharePoint集成:一是利用SharePoint 2013及更高版本提供的RESTful API进行数据交互和操作;二是开发独立的“自托管应用”,这些应用可以使用Go语言编写,并在外部服务器上运行,从而扩展SharePoint的功能。 Go语言…

    2025年12月16日
    000
  • Go语言中OpenPGP密钥的生成与管理

    本文深入探讨了在Go语言中使用go.crypto/openpgp库生成和管理PGP密钥的方法。我们将详细介绍如何创建PGP实体、提取公钥,并重点阐述如何利用packet.Config配置自定义密钥长度,从而解决早期版本中密钥长度固定的问题。通过示例代码,读者将掌握生成、序列化及使用PGP密钥的专业技…

    2025年12月16日
    000
  • Go语言日期与时间处理详解:time 包核心机制与实践

    Go语言通过其内置的time包提供了一套强大且精确的日期时间处理机制。它以Time结构体为核心,能够以纳秒级精度表示时间瞬间,且在内部表示中不考虑闰秒。time包依赖IANA时区数据库处理复杂的时区和夏令时规则,确保全球时间信息的准确性。本文将深入探讨Time结构体的设计、时区管理,并提供实际应用示…

    2025年12月16日
    000
  • Golang如何实现goroutine池

    答案:Go语言中通过goroutine池可控制并发、复用资源,核心为channel传递任务与固定worker消费。示例实现包含任务队列、worker数量控制、启动关闭机制,使用有缓冲channel避免阻塞,select监听done信号实现优雅退出,具备并发安全与资源控制特性,适用于限制并发场景。 G…

    2025年12月16日
    000
  • Go App Engine中goauth2与urlfetch的集成指南

    本文旨在指导开发者如何在Google App Engine Go环境中,将goauth2认证库与appengine/urlfetch包进行有效集成。核心解决方案在于为oauth.Transport配置一个urlfetch.Transport作为其底层传输机制,从而克服App Engine对标准htt…

    2025年12月16日
    000
  • 如何使用互斥锁同步 Goroutine 执行

    本文将探讨如何利用 Go 语言的 sync 包中的互斥锁 (Mutex) 来控制 Goroutine 的执行,确保在特定时间只有一个 Goroutine 能够运行。 在并发编程中,多个 Goroutine 可能会同时访问和修改共享数据,这可能导致竞态条件和数据不一致的问题。为了避免这些问题,我们需要…

    2025年12月16日
    000
  • 使用 Go 语言与 Microsoft SharePoint 交互

    本文旨在探讨如何使用 Go 语言与 Microsoft SharePoint 进行交互。虽然 SharePoint 的功能繁多,但通过 SharePoint 2013 应用和 RESTful API,我们可以利用 Go 语言开发自托管应用或直接与 SharePoint API 进行通信。本文将介绍这…

    2025年12月16日
    000
  • 掌握Go语言文档:函数、方法与接口的解析

    本文旨在指导Go语言开发者高效阅读官方文档,重点解析如何区分包级函数与类型方法,理解函数签名中的接收者概念,以及如何处理接口类型兼容性问题。通过具体案例,帮助读者快速定位所需信息,提升文档查阅效率。 Go语言的官方文档是学习和使用Go的重要资源,但初学者有时会对其结构感到困惑,尤其是在区分包级函数与…

    2025年12月16日
    000
  • Golang panic和recover有什么区别

    panic用于触发运行时恐慌,终止函数执行并向上蔓延;recover则在defer中捕获panic,阻止程序崩溃。两者配合实现异常控制,类似throw/catch,但应仅用于严重错误,普通错误推荐error处理。 panic 和 recover 是 Go 语言中用于处理严重错误的机制,它们的作用完全…

    2025年12月16日
    000
  • Go语言中自定义错误处理的实践指南

    本教程旨在深入探讨Go语言中惯用的错误处理机制,从基础的error接口和errors.New函数出发,逐步介绍如何通过多返回值模式处理错误。教程将指导读者创建和使用自定义错误类型,超越简单的错误码,实现更具语义化和可扩展性的错误报告与处理,并提供实际的代码示例和最佳实践建议。 Go语言中的错误处理哲…

    2025年12月16日
    000
  • 如何在 Go 中实现内嵌类型默认行为并引用外部类型属性

    本文探讨 Go 语言中如何为内嵌类型提供默认方法实现,并使其能够能够访问外部(嵌入)类型的属性。Go 的嵌入机制是组合而非传统意义上的继承,因此直接在内嵌类型中获取外部类型信息是不可行的。文章将提供两种 Go 惯用的解决方案:通过方法参数显式传递外部类型实例,以及利用接口定义行为契约,从而实现灵活且…

    2025年12月16日
    000
  • Go语言文档导航:高效查找函数与接口使用

    本教程旨在解决Go语言文档使用中的常见困惑,特别是如何区分同名函数、理解接收器以及查找接受特定接口的函数。文章将通过具体示例,深入解析Go函数声明的语法,阐明包级函数与方法(带接收器的函数)的区别,并指导读者如何利用Go语言的接口特性,高效地在文档中定位所需功能,从而提升Go语言的学习和开发效率。 …

    2025年12月16日
    000
  • 在Go语言中实现标准输出(stdout)的行内更新与覆盖

    本文深入探讨Go语言中如何在标准输出(stdout)上实现内容的行内更新与覆盖。核心在于理解stdout作为流的特性,以及利用终端特有的控制字符。通过使用回车符r,可以将光标移至当前行首,从而实现后续输出对先前内容的覆盖,常用于进度显示等场景。文章同时强调了此方法对输出环境(是否为终端)的依赖性。 …

    2025年12月16日
    000
  • Go App Engine中goauth2与urlfetch的集成方法

    本文旨在解决Go App Engine环境中,goauth2库无法直接使用标准http.Client的问题。通过详细阐述如何在oauth.Transport配置中指定urlfetch.Transport,本教程提供了一种在App Engine上成功实现goauth2认证与外部资源访问的专业方法,确保…

    2025年12月16日
    000
  • Go语言与Microsoft SharePoint集成指南

    Go语言可以有效集成Microsoft SharePoint,主要通过两种途径:一是利用SharePoint提供的RESTful API进行数据交互,Go的标准HTTP客户端库即可轻松实现;二是通过SharePoint应用模型开发自托管应用,这种模型支持使用包括Go在内的任何语言编写后端逻辑。 1.…

    2025年12月16日
    000

发表回复

登录后才能评论
关注微信