gpt4 book ai didi

reactjs - 从外部组件 react 测试库触发回调

转载 作者:行者123 更新时间:2023-12-02 02:30:56 25 4
gpt4 key购买 nike

我正在尝试弄清楚如何使用 jest 和 React 测试库来测试作为 props 给出的回调以对功能组件使用react。

示例场景:我正在测试一个呈现模式的组件。当用户单击模态框上的“关闭”按钮时,父组件会隐藏模态框。所以逻辑是这样的:

 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>
</>
}
}

我在父组件的测试中模拟模态,因为我不想依赖实际的模态组件。使用 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?

});

最佳答案

对于您的示例,实际上不需要模拟 MyModal 组件,除非 MyModal 组件具有许多外部依赖项。参见 testing-recipes.html#mocking-modules .

为了触发onClose函数,还需要在MyModal组件上触发onClick函数。

此外,您没有正确模拟 MyModal 组件。这是一个工作示例:

ParentComp.tsx:

import React, { useState } from 'react';
import { MyModal } from './MyModal';

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

MyModal.tsx:

import React from 'react';

export const MyModal = ({ showModal, onClose }) => {
return (
showModal && (
<>
<div>This is a modal</div>
<button data-testid="close-modal-button" onClick={onClose}>
Close
</button>
</>
)
);
};

ParentComp.test.tsx:

import { fireEvent, render } from '@testing-library/react';
import React from 'react';
import { ParentComp } from './ParentComp';

function MockedMyModal({ onClose, showModal }) {
return (
showModal && (
<>
<div>This is a mocked modal</div>
<button data-testid="my-modal" onClick={onClose}>
Close
</button>
</>
)
);
}

jest.mock('./MyModal', () => {
return { MyModal: MockedMyModal };
});

describe('65038548', () => {
afterAll(() => {
jest.resetAllMocks();
});
it('should open the modal', () => {
const { getByTestId } = render(<ParentComp></ParentComp>);
const openModalButton = getByTestId('open-modal-button');

fireEvent.click(openModalButton);
const myModal = getByTestId('my-modal');

expect(myModal).toBeDefined();
});

it('should close the modal', () => {
const { getByTestId, queryByText } = render(<ParentComp></ParentComp>);
const openModalButton = getByTestId('open-modal-button');
fireEvent.click(openModalButton);

const closeModalButton = getByTestId('my-modal');
expect(closeModalButton).toBeDefined();

fireEvent.click(closeModalButton);

expect(queryByText('This is a mocked modal')).toBeNull();
});
});

为什么使用 queryByText 而不是 getByTestId,参见 Asserting elements are not present

单元测试结果:

 PASS  examples/65038548/ParentComp.test.tsx
65038548
✓ should pass (34 ms)

----------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------------|---------|----------|---------|---------|-------------------
All files | 87.5 | 100 | 66.67 | 85.71 |
ParentComp.tsx | 87.5 | 100 | 66.67 | 85.71 | 8
----------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 5.848 s

源代码:https://github.com/mrdulin/jest-v26-codelab/tree/main/examples/65038548

关于reactjs - 从外部组件 react 测试库触发回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65038548/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com