use*_*545 3 reactjs jestjs react-testing-library react-hooks
我试图弄清楚如何使用 jest 和 React 测试库来测试作为 props 给出的回调,以对功能组件做出反应。
示例场景:我正在测试一个呈现模式的组件。当用户单击模式上的“关闭”按钮时,父组件将隐藏模式。所以逻辑是这样的:
const ParentComp = () => {
const [openModal, setOpenModal] = useState(false);
return (
<>
<MyModal showModal={openModal} onClose={() => setOpenModal(false)} />
<button data-testid="open-modal-button" onClick={()=> setOpenModal(true)}>Test</button>
</>
}
const MyModal = ({showModal, onClose}) => {
return (
{showModal && <>
<div>This is a modal</div>
<button data-testid="close-modal-button" onClick={onClose}>Close</button>
</>
}
}
Run Code Online (Sandbox Code Playgroud)
我在父组件的测试中模拟模态,因为我不想依赖实际的模态组件。使用 React 测试库,如何触发父组件中的 onClose 以便测试 setOpenModal(false)?
jest.mock('../MyModal');
beforeEach(() => {
MyModal.mockImplementation(() => <div data-testid="my-modal" />);
});
it('should close the modal' () => {
const { container, getByTestId } = render(
<MyParentComp />
);
const openModalButton = getByTestId('open-modal-button');
fireEvent.click(openModalButton);
const myModal = getByTestId('my-modal');
expect(myModal).toBeDefined();
//How to test setOpenModal(false) on parent component?
Run Code Online (Sandbox Code Playgroud)
});
对于您的示例,实际上不需要模拟MyModal组件,除非MyModal组件具有许多外部依赖项。请参阅testing-recipes.html#mocking-modules。
为了触发该onClose功能,您仍然需要onClick在MyModal。
此外,您没有正确模拟 MyModal 组件。这是一个工作示例:
\nParentComp.tsx:
import React, { useState } from \'react\';\nimport { MyModal } from \'./MyModal\';\n\nexport const ParentComp = () => {\n const [openModal, setOpenModal] = useState(false);\n return (\n <>\n <MyModal showModal={openModal} onClose={() => setOpenModal(false)} />\n <button data-testid="open-modal-button" onClick={() => setOpenModal(true)}>\n Test\n </button>\n </>\n );\n};\nRun Code Online (Sandbox Code Playgroud)\nMyModal.tsx:
import React from \'react\';\n\nexport const MyModal = ({ showModal, onClose }) => {\n return (\n showModal && (\n <>\n <div>This is a modal</div>\n <button data-testid="close-modal-button" onClick={onClose}>\n Close\n </button>\n </>\n )\n );\n};\nRun Code Online (Sandbox Code Playgroud)\nParentComp.test.tsx:
import { fireEvent, render } from \'@testing-library/react\';\nimport React from \'react\';\nimport { ParentComp } from \'./ParentComp\';\n\nfunction MockedMyModal({ onClose, showModal }) {\n return (\n showModal && (\n <>\n <div>This is a mocked modal</div>\n <button data-testid="my-modal" onClick={onClose}>\n Close\n </button>\n </>\n )\n );\n}\n\njest.mock(\'./MyModal\', () => {\n return { MyModal: MockedMyModal };\n});\n\ndescribe(\'65038548\', () => {\n afterAll(() => {\n jest.resetAllMocks();\n });\n it(\'should open the modal\', () => {\n const { getByTestId } = render(<ParentComp></ParentComp>);\n const openModalButton = getByTestId(\'open-modal-button\');\n\n fireEvent.click(openModalButton);\n const myModal = getByTestId(\'my-modal\');\n\n expect(myModal).toBeDefined();\n });\n\n it(\'should close the modal\', () => {\n const { getByTestId, queryByText } = render(<ParentComp></ParentComp>);\n const openModalButton = getByTestId(\'open-modal-button\');\n fireEvent.click(openModalButton);\n\n const closeModalButton = getByTestId(\'my-modal\');\n expect(closeModalButton).toBeDefined();\n\n fireEvent.click(closeModalButton);\n\n expect(queryByText(\'This is a mocked modal\')).toBeNull();\n });\n});\nRun Code Online (Sandbox Code Playgroud)\n为什么使用queryByText而不是getByTestId,请参阅断言元素不存在
单元测试结果:
\n PASS examples/65038548/ParentComp.test.tsx\n 65038548\n \xe2\x9c\x93 should pass (34 ms)\n\n----------------|---------|----------|---------|---------|-------------------\nFile | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s \n----------------|---------|----------|---------|---------|-------------------\nAll files | 87.5 | 100 | 66.67 | 85.71 | \n ParentComp.tsx | 87.5 | 100 | 66.67 | 85.71 | 8 \n----------------|---------|----------|---------|---------|-------------------\nTest Suites: 1 passed, 1 total\nTests: 1 passed, 1 total\nSnapshots: 0 total\nTime: 5.848 s\nRun Code Online (Sandbox Code Playgroud)\n源代码:https://github.com/mrdulin/jest-v26-codelab/tree/main/examples/65038548
\n| 归档时间: |
|
| 查看次数: |
14696 次 |
| 最近记录: |