A combination between the two answers, plus the handling of the requests is what has worked for me. In this example you don't provide a URL to do the POST request, but the Dragger component of Ant Design has this option available.
I just want to share my solution for this question + an extra issue I found while using the action
property, just to save you time.
To test the Dragger I did this:
test("Dragger functionality", async () => {
const flushPromises = () => new Promise(setImmediate);
const file = new File(["{test: 1}"], "test.json", {type: 'application/json'})
const input = screen.getByTestId("uploader");
// I added the data-testid property to the Dragger element, with the value "uploader"
await act(async () => {
fireEvent.change(input, {target: {files: [file]}});
});
await flushPromises();
});
The userEvent.upload
method never worked for me. I've been using the userEvent
for all the other tests but I couldn't make it work in this case.
Extra: If you are using the Dragger as I was
<Dragger multiple={true} accept={".json"} onChange={onChange} action={"/test"} data-testid={"uploader"}>
with the onChange
and action
properties, you will probably not get the onChange
called.
To make it work, you have to handle the POST request that is made, in this case to the /test
. So, the complete test would be:
import { act, fireEvent, render, screen } from "@testing-library/react";
import { setupServer } from "msw/node";
import { rest } from "msw";
import React from "react";
import { Upload } from "antd";
const { Dragger } = Upload;
const onChangeMock = jest.fn();
const server = setupServer(rest.post("/test", (req, res, ctx) => {
return res(ctx.json({response: "200 OK"}));
}));
beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
test("Dragger functionality", async () => {
const flushPromises = () => new Promise(setImmediate);
render (
<Dragger multiple={true} accept={".json"} onChange={onChangeMock} action={"/test"} data-testid={"uploader"}>
<p className="ant-upload-drag-icon">
<InboxOutlined />
</p>
<p className="ant-upload-text">{"description"}</p>
<p className="ant-upload-hint">{"hint"}</p>
</Dragger>
);
const file = new File(["{test: 1}"], "test.json", {type: 'application/json'})
const input = screen.getByTestId("uploader");
// I added the data-testid property to the Dragger element, with the value "uploader"
await act(async () => {
fireEvent.change(input, {target: {files: [file]}});
});
await flushPromises();
expect(onChangeMock).toBeCalled();
});
Hopefully this is useful for someone.