최근에 새 브라우저 창을 여는 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!