reactjs - วิธีใช้ฟังก์ชันที่ประกาศใน context provider ในการทดสอบ react?
ฉันกำลังพยายามทดสอบฟังก์ชัน showModal ที่ฉันประกาศใน context provider:
export const ModalProvider = ({ children }: ProviderProps) => {
const [isOpen, setIsOpen] = useState<boolean>(false);
const [titleText, setTitleText] = useState<string>('');
const [contentText, setContentText] = useState<string>('');
const [hideCloseButton, setHideCloseButton] = useState<boolean>(false);
const showModal: ShowModalProps = useCallback((title, content, hideCloseButton) => {
setIsOpen(true);
setTitleText(title);
setContentText(content);
setHideCloseButton(hideCloseButton);
}, []);
const closeModal = () => {
setIsOpen(false);
};
return (
<ModalContext.Provider
value={{
isOpen,
setIsOpen,
showModal,
closeModal,
titleText,
contentText,
hideCloseButton
}}
>
{children}
</ModalContext.Provider>
);
};
ตอนนี้ฉันต้องการทดสอบฟังก์ชันนี้
describe('Modal testing', () => {
it(`Should render popup modal`, () => {
render(
<ModalProvider>
<HomePage />
</ModalProvider>
);
showModal('TEST', 'TEST Text', false);
const errorMessage = screen.getByText('TEST Text');
expect(errorMessage).toBeDefined();
});
});
ฉันได้รับข้อผิดพลาดว่า showModal ไม่ได้ถูกกำหนด แต่ฉันได้ห่อหน้าด้วย provider แล้ว ดังนั้นฉันไม่แน่ใจว่าจะเข้าถึงฟังก์ชันนี้และเรียกใช้งานในทดสอบได้อย่างไร
คำตอบ #1
เราควรทดสอบพฤติกรรมของคอมโพเนนต์ ModalProvider ในการทดสอบ เราจำเป็นต้องมีคอมโพเนนต์ทดสอบเพื่อใช้ค่าจาก context
ฉันใช้องค์ประกอบกล่องโต้ตอบ HTML เป็นกิริยาช่วย
เราจำเป็นต้องหาปุ่ม "show modal" และเรียกเหตุการณ์คลิกบนมัน ตัวจัดการคลิกจะเรียกฟังก์ชัน showModal จากค่า context หลังจากสถานะเปลี่ยนแปลง ModalProvider และคอมโพเนนต์ children จะทำการเรนเดอร์ใหม่ ตอนนี้เราสามารถตรวจสอบว่า dialog อยู่ในเอกสาร(หน้าจอ) หรือไม่ หากมันอยู่ในเอกสาร เราสามารถตรวจสอบหัวข้อและเนื้อหาของมันได้
เช่น
index.tsx:
import React, { useCallback, useState } from "react";
export interface ModalContextType {
isOpen: boolean;
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
showModal: (title: string, content: string, hideCloseButton: boolean) => void;
closeModal: () => void;
titleText: string;
contentText: string;
hideCloseButton: boolean;
}
export const ModalContext = React.createContext<ModalContextType>({} as ModalContextType)
export const ModalProvider = ({ children }) => {
const [isOpen, setIsOpen] = useState<boolean>(false);
const [titleText, setTitleText] = useState<string>('');
const [contentText, setContentText] = useState<string>('');
const [hideCloseButton, setHideCloseButton] = useState<boolean>(false);
const showModal = useCallback((title, content, hideCloseButton) => {
setIsOpen(true);
setTitleText(title);
setContentText(content);
setHideCloseButton(hideCloseButton);
}, []);
const closeModal = () => {
setIsOpen(false);
};
return (
<ModalContext.Provider
value={{
isOpen,
setIsOpen,
showModal,
closeModal,
titleText,
contentText,
hideCloseButton
}}
>
{children}
</ModalContext.Provider>
);
};
index.test.tsx:
import { render, fireEvent, screen } from "@testing-library/react"
import '@testing-library/jest-dom';
import React from "react"
import { useContext } from "react"
import { ModalContext, ModalProvider } from "."
describe('74101831', () => {
test('should pass', () => {
const TestComp = () => {
const { isOpen, titleText, contentText, hideCloseButton, showModal } = useContext(ModalContext);
return <div>
<dialog open={isOpen} title={titleText} >
<div>{contentText}</div>
{!hideCloseButton && <button>close</button>}
</dialog>
<button onClick={() => showModal('dialog title', 'dialog content', false)}>show modal</button>
</div>
}
render(<ModalProvider><TestComp /></ModalProvider>);
fireEvent.click(screen.getByRole('button', { name: 'show modal' }));
expect(screen.getByRole('dialog')).toBeInTheDocument();
expect(screen.getByRole('dialog')).toHaveAttribute('title', 'dialog title');
expect(screen.getByRole('dialog')).toHaveAttribute('open');
expect(screen.getByRole('button', { name: 'close' })).toBeInTheDocument();
expect(screen.getByText('dialog content')).toBeInTheDocument();
});
});
ผลการทดสอบ:
PASS stackoverflow/74101831/index.test.tsx (11.102 s)
74101831
✓ should pass (142 ms)
-----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-----------|---------|----------|---------|---------|-------------------
All files | 93.75 | 100 | 66.67 | 93.33 |
index.tsx | 93.75 | 100 | 66.67 | 93.33 | 29
-----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 11.656 s
เวอร์ชันของแพ็กเกจ:
"@testing-library/react": "^11.2.7",
"@testing-library/jest-dom": "^5.11.6",
"jest": "^26.6.3",
"react": "^16.14.0",
"react-dom": "^16.14.0",
