我想从React组件中的react-dropzone库测试onDrop方法。我正在使用Jest,React测试库。我正在创建模拟文件,并尝试在输入中删除此文件,但在console.log文件中仍然等于空数组。您有什么想法吗?
- 包. json**
"typescript": "^3.9.7",
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.0.4",
"@types/jest": "^26.0.13",
"jest": "^26.4.2",
"ts-jest": "^26.3.0",
"react-router-dom": "^5.1.2",
"react-dropzone": "^10.1.10",
"@types/react-dropzone": "4.2.0",
- 模态导入文件. tsx**
import React, { FC, useState } from "react";
import { Box, Button, Dialog, DialogContent, DialogTitle, Grid } from "@material-ui/core";
import { useDropzone } from "react-dropzone";
import AttachFileIcon from "@material-ui/icons/AttachFile";
import DeleteIcon from "@material-ui/icons/Delete";
interface Props {
isOpen: boolean;
}
interface Events {
onClose: () => void;
}
const ModalImportFile: FC<Props & Events> = props => {
const { isOpen } = props as Props;
const { onClose } = props as Events;
const [files, setFiles] = useState<Array<File>>([]);
const { getRootProps, getInputProps, open } = useDropzone({
onDrop: (acceptedFiles: []) => {
setFiles(
acceptedFiles.map((file: File) =>
Object.assign(file, {
preview: URL.createObjectURL(file),
}),
),
);
},
noClick: true,
noKeyboard: true,
});
const getDragZoneContent = () => {
if (files && files.length > 0)
return (
<Box border={1} borderRadius={5} borderColor={"#cecece"} p={2} mb={2}>
<Grid container alignItems="center" justify="space-between">
<Box color="text.primary">{files[0].name}</Box>
<Box ml={1} color="text.secondary">
<Button
startIcon={<DeleteIcon color="error" />}
onClick={() => {
setFiles([]);
}}
/>
</Box>
</Grid>
</Box>
);
return (
<Box border={1} borderRadius={5} borderColor={"#cecece"} p={2} mb={2} style={{ borderStyle: "dashed" }}>
<Grid container alignItems="center">
<Box mr={1} color="text.secondary">
<AttachFileIcon />
</Box>
<Box color="text.secondary">
<Box onClick={open} component="span" marginLeft="5px">
Download
</Box>
</Box>
</Grid>
</Box>
);
};
const closeHandler = () => {
onClose();
setFiles([]);
};
return (
<Dialog open={isOpen} onClose={closeHandler}>
<Box width={520}>
<DialogTitle>Import</DialogTitle>
<DialogContent>
<div data-testid="container" className="container">
<div data-testid="dropzone" {...getRootProps({ className: "dropzone" })}>
<input data-testid="drop-input" {...getInputProps()} />
{getDragZoneContent()}
</div>
</div>
</DialogContent>
</Box>
</Dialog>
);
};
export default ModalImportFile;
- 模态导入文件. test. tsx**
import React from "react";
import { render, screen, fireEvent } from "@testing-library/react";
import ModalImportFile from "../../components/task/elements/ModalImportFile";
const props = {
isOpen: true,
onClose: jest.fn(),
};
beforeEach(() => jest.clearAllMocks());
describe("<ModalImportFile/>", () => {
it("should drop", async () => {
render(<ModalImportFile {...props} />);
const file = new File([JSON.stringify({ ping: true })], "ping.json", { type: "application/json" });
const data = mockData([file]);
function dispatchEvt(node: any, type: any, data: any) {
const event = new Event(type, { bubbles: true });
Object.assign(event, data);
fireEvent(node, event);
}
function mockData(files: Array<File>) {
return {
dataTransfer: {
files,
items: files.map(file => ({
kind: "file",
type: file.type,
getAsFile: () => file,
})),
types: ["Files"],
},
};
}
const inputEl = screen.getByTestId("drop-input");
dispatchEvt(inputEl, "dragenter", data);
});
}
4条答案
按热度按时间f87krz0w1#
使用rokki's答案(https://stackoverflow.com/a/64643985/9405587),我重写了测试组件,以便更容易理解。
模态导入文件.test.tsx
dwthyt8l2#
把
fireEvent(node, event);
改成fireEvent.drop(node, event);
怎么样?vuv7lop33#
参考文献:www.example.comhttps://jestjs.io/docs/jest-object#jestrequireactualmodulename
requireActual
返回实际的模块而不是模拟模块,跳过对模块是否应该接收模拟实现的所有检查。
ttcibm8c4#
虽然接受的答案确实触发了事件
onDrop
,但这还不足以让我使用useDropzone()
进行测试,因为钩子的状态(如acceptedFiles
)没有更新。我发现this代码片段使用
userEvent.upload(<input>, <files>)
将文件上传到嵌套的<input>
。我将在这里粘贴相关代码,以防链接丢失。应用程序测试tsx
应用程序tsx
注意,设置为
data-testid="dropzone"
的元素是<input>
,而不是<div>
,这是userEvent.upload
能够充分执行上载所必需的。