首頁 > web前端 > js教程 > 使用 Jest 在 JavaScript 測試 window.open()

使用 Jest 在 JavaScript 測試 window.open()

Patricia Arquette
發布: 2024-12-10 16:50:12
原創
506 人瀏覽過

Testing window.open() in JavaScript with Jest

我最近必須為開啟新瀏覽器視窗的 React 元件編寫測試。為了打開新窗口,我在程式碼中使用了 window.open() 。這使得該元件易於編寫,但我必須以不同的方式思考如何為此編寫測試。

有關 window.open() 方法的更多信息,請參閱 mdn 網路文件。

為了設定位元或背景,我有一個 React 元件,它有一個帶有幾個輸入的簡單表單。當使用者完成輸入並提交表單後,它會開啟一個指向指定 URL 的新窗口,並將輸入作為 URL 參數。

要測試的組件

這是該組件的一個非常簡化的版本作為演示。我建議使用像react-hook-form這樣的東西來為您的表單添加驗證。

// MyForm.js
import 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 (
    <form onSubmit={onSubmit}>
      <label htmlFor="name">Name</label>
      <input name="name">



<p>Now we have our component, lets think about the test for it.</p>

<h2>
  
  
  What I’d normally test
</h2>

<p>Normally I would test what has been rendered in my component, using assertions such as expect the component to have text content or assert the url is what is expected (using window.location.href), but I quickly realised that approach won’t work in jest for this example.</p>

<p>Window.open opens a new browser window, so it doesn’t affect the component we are testing. We can’t see what is inside the new window or what its url is as it is outside of the scope of the component we are testing.</p>

<p>So how do we test something that is outside of what we can see? We don’t actually need to test that a new window is opened as that would be testing the window interface’s functionality and not our code. Instead, we just need to test that the window.open method is called.</p>

<h2>
  
  
  Mocking window.open()
</h2>

<p>Therefore we need to mock window.open() and test that it was called inside our code.<br>
</p>

<pre class="brush:php;toolbar:false">// Mock window.open
global.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.js
import 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(<MyForm baseURL="http://example.com" />);

    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 測試 window.open()的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板