// Delete.jsx
import React, {useCallback, useRef} from "react"
import {useDispatch} from "react-redux"
import {ModalComponent, modalOpen} from "../Modal"
export function Delete () {
const dispatch = useDispatch()
const modalRef = useRef(null)
const handleDelete = () => {
dispatchEvent(deleteData())
modalRef.current.close
}
return (
<Type>
<Button
onClick={modalOpen(modalRef)}
>
Delete
</Button>
<ModalComponent func={handleDelete} refer={modalRef} />
</Type>
)
}
// ModalComponent.jsx
import React, {useCallback} from "react"
export function ModalComponent (props) {
const modalRef = props.refer
return (
<Modal
ref={modalRef}
onClose={modalClose(modalRef)}
>
<Type>
Are you sure ?
</Type>
<Type>
<ButtonGroup>
<Button
id='DeleteButton'
onClick={modalClose(modalRef)}
>
Close
</Button>
<Button
onClick={props.func}
>
Confirm
</Button>
</ButtonGroup>
</Type>
</Modal>
)
}
export const modalOpen = (refModal) => {
return useCallback(
() => {
refModal.current.open()
}, [refModal]
)
}
export const modalClose = (refModal) => {
return useCallback(
() => {
refModal.current.close()
}, [refModal]
)
}
以上是Delete和ModalComponent的代码,我正在尝试为Delete按钮编写单元测试用例。
// Delete.test.js
import React from "react"
import {fireEvent, render} from "@testing-library/react"
import * as modal from '../ModalComponent'
jest.mock('react-redux', () => ({
...jest.requireActual('react-redux'),
useDispatch: jest.fn()
}))
describe('Delete button', () => {
it('should open modal when delete button is called', () => {
const modalSpy = jest.spyOn(modal, 'modalOpen').mockImplementation(() => jest.fn())
const component = render(
<Delete />
)
const button = component.container.querySelector('#DeleteButton')
fireEvent.click(button)
expect(modalSpy).toHaveBeenCalled()
})
})
有人可以帮我处理模式事件,以便我可以测试句柄编辑吗?
不要嘲笑你正在尝试进行单元测试的内容。您的单元测试应该反映用户或其他组件如何与该组件交互,例如通过其渲染的 UI 和 props。
由于您无法共享
Modal
组件,我创建了一个模拟模态组件,该组件通过 React 引用公开打开和关闭处理程序。
模拟模态组件:
import React, {
forwardRef,
useImperativeHandle,
useState
} from "react";
const Modal = forwardRef((props, ref) => {
const [open, setOpen] = useState(false);
useImperativeHandle(
ref,
() => ({
open: () => setOpen(true),
close: () => setOpen(false)
}),
[]
);
return open ? (
<div data-testid="modal">
<button type="button" onClick={props.onClose}>
x
</button>
<div>{props.children}</div>
</div>
) : null;
});
删除
const modalOpen = (refModal) => () => {
refModal.current.open();
};
const modalClose = (refModal) => () => {
refModal.current.close();
};
export default function Delete() {
// const dispatch = useDispatch();
const modalRef = useRef(null);
const handleDelete = () => {
// dispatchEvent(deleteData())
modalRef.current.close();
};
return (
<Type>
<Button onClick={modalOpen(modalRef)}>Delete</Button>
<ModalComponent func={handleDelete} refer={modalRef} />
</Type>
);
}
删除单元测试
import React from "react";
import { fireEvent, render } from "@testing-library/react";
import "@testing-library/jest-dom";
import Delete from "./Delete";
describe("Delete button", () => {
it("should open modal when delete button is called", () => {
const { queryByText, queryByTestId } = render(<Delete />);
// Assert that the modal is not current in the DOM
expect(queryByTestId("modal")).not.toBeInTheDocument();
// Click delete button to toggle the modal open
fireEvent.click(queryByText("Delete"));
// Assert that the modal is now in the DOM
expect(queryByTestId("modal")).toBeInTheDocument();
// Click modal's close button to toggle the modal closed
fireEvent.click(queryByText("Close"));
// Assert that the modal is not current in the DOM
expect(queryByTestId("modal")).not.toBeInTheDocument();
});
});
当您更新代码并取消注释
useDispatch
挂钩和 dispatch
调用时,您还需要为测试创建一个 Redux 存储。
基本示例:
import React from "react";
import { fireEvent, render } from "@testing-library/react";
import "@testing-library/jest-dom";
import { configureStore } from "@reduxjs/toolkit";
import { Provider } from "react-redux";
import reducer from "../path/to/rootReducer";
import Delete from "./Delete";
const store = configureStore({
reducer,
});
const Providers = ({ children }) => (
<Provider store={store}>
{children}
</Provider>
);
describe("Delete button", () => {
it("should open modal when delete button is called", () => {
const { .... } = render(<Delete />, { wrapper: Providers });
... testing code ...
});
});
请参阅 Redux Writing Tests 文档,了解更多一般测试信息和策略。