Rumah >hujung hadapan web >tutorial js >Menguji window.open() dalam JavaScript dengan Jest

Menguji window.open() dalam JavaScript dengan Jest

Patricia Arquette
Patricia Arquetteasal
2024-12-10 16:50:12473semak imbas

Testing window.open() in JavaScript with Jest

Baru-baru ini saya terpaksa menulis ujian untuk komponen React yang membuka tetingkap penyemak imbas baharu. Untuk membuka tetingkap baharu saya menggunakan window.open() dalam kod saya. Ini menjadikan komponen mudah untuk ditulis, tetapi saya terpaksa berfikir secara berbeza tentang cara menulis ujian untuk ini.

Maklumat lanjut tentang kaedah window.open() tersedia pada dokumen web mdn.

Untuk menetapkan sedikit atau latar belakang, saya mempunyai komponen React yang mempunyai bentuk ringkas dengan beberapa input. Apabila pengguna melengkapkan input dan menyerahkan borang, ia membuka tetingkap baharu ke URL yang ditentukan dengan input sebagai parameter URL.

Komponen untuk diuji

Berikut ialah versi komponen yang sangat ringkas sebagai demonstrasi. Saya akan mengesyorkan menggunakan sesuatu seperti react-hook-form untuk menambahkan pengesahan pada borang anda.

// 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();

Kini kami boleh menetapkan nilai dalam input, menyerahkan borang kami dan kemudian menguji bahawa window.open dipanggil. Kita boleh menggunakan fireEvent untuk menetapkan nilai input dan menekan butang hantar.

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)" })
);

Perlu membaca dokumentasi untuk pertimbangan fireEvent. Anda mungkin mahu menggunakan acara pengguna sebaliknya bergantung pada kes penggunaan anda.

Kami mahu menunggu kaedah berjalan. Kita boleh melakukannya menggunakan waitFor().

await waitFor(() => {
  expect(global.open).toHaveBeenCalled();
});

Untuk memastikan kami tidak membuka banyak tetingkap baharu, kami boleh menyemak sama ada kami hanya memanggil window.open sekali.

await waitFor(() => {
  expect(global.open).toHaveBeenCalledTimes(1);
});

Kami juga boleh menyemak argumen yang digunakan untuk kaedah itu, menghantar URL yang kami harapkan sebagai argumen pertama dan sasaran sebagai yang kedua.

await waitFor(() => {
  expect(global.open).toHaveBeenCalledWith(
    "http://example.com?name=Test%20Name&subject=An%20example%20subject",
    "_blank"
  );
});

Fail ujian lengkap

Berikut ialah fail ujian lengkap untuk rujukan anda.

// 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"
      );
    });
  });
});

Foto oleh energepic.com di StockSnap

Atas ialah kandungan terperinci Menguji window.open() dalam JavaScript dengan Jest. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn