gpt4 book ai didi

javascript - 如何正确地 mock `antd` Upload Dragger?

转载 作者:行者123 更新时间:2023-12-04 11:56:38 27 4
gpt4 key购买 nike

我的项目中有以下 react 代码

import React from 'react';
import { Upload } from 'antd';

const { Dragger } = Upload;

...

<Dragger
accept={ACCEPTED_FORMATS}
beforeUpload={beforeUpload}
data-testid="upload-dragger"
maxCount={1}
onChange={({ file: { status } }) => {
if (status === 'done') onUploadComplete();
}}
progress={progress}
showUploadList={false}
>
{/* here i have a button, code ommited for clarity, if needed i'll post it */}
</Dragger>
我想测试一下回调函数 onUploadComplete()当 file.status 为 'done' 时调用.
这是我现在进行测试的方式:
  • 我有一个 jest.mock 来模拟一个永远成功的愚蠢请求

  • import React from 'react';
    import { fireEvent, render, waitFor } from '@testing-library/react';
    import { act } from 'react-dom/test-utils';
    import { DraggerProps } from 'antd/lib/upload';
    import userEvent from '@testing-library/user-event';

    import UploadCompanyLogo from '../UploadCompanyLogo'; // This is the component where the dragger is placed

    jest.mock('antd', () => {
    const antd = jest.requireActual('antd');
    const { Upload } = antd;
    const { Dragger } = Upload;

    const MockedDragger = (props: DraggerProps) => {
    console.log('log test');
    return (
    <Dragger
    {...props}
    action="greetings"
    customRequest={({ onSuccess }) => {
    setTimeout(() => {
    onSuccess('ok');
    }, 0);
    }}
    />
    );
    };

    return { ...antd, Upload: { ...Upload, Dragger: MockedDragger } };
    });
  • 测试本身(与模拟相同的文件),它在其中呈现组件(将导入 antd),模拟上传,然后检查是否已调用回调。
  • it('completes the image upload', async () => {
    const flushPromises = () => new Promise(setImmediate);

    const { getByTestId } = render(elementRenderer({ onUploadComplete }));

    const file = new File(['(⌐□_□)'], 'chucknorris.png', { type: 'image/png' });

    const uploadDragger = await waitFor(() => getByTestId('upload-dragger'));

    await act(async () => {
    userEvent.upload(uploadDragger, file);
    });

    await flushPromises();

    expect(onUploadComplete).toHaveBeenCalledTimes(1);
    expect(onUploadComplete).toHaveBeenCalledWith();
    });
  • 元素渲染器
  • const elementRenderer = ({
    onUploadComplete = () => {}
    }) => (
    <ApplicationProvider>
    <UploadCompanyLogo
    onUploadComplete={onUploadComplete}
    />
    </ApplicationProvider>
    );
  • 应用程序提供商
  • import React, { PropsWithChildren } from 'react';
    import { ConfigProvider as AntdProvider } from 'antd';
    import { RendererProvider as FelaProvider } from 'react-fela';
    import { createRenderer } from 'fela';
    import { I18nextProvider } from 'react-i18next';

    import antdExternalContainer, {
    EXTERNAL_CONTAINER_ID,
    } from 'src/util/antdExternalContainer';
    import { antdLocale } from 'src/util/locales';
    import rendererConfig from 'src/fela/felaConfig';
    import i18n from 'src/i18n';

    const ApplicationProvider = (props: PropsWithChildren<{}>) => {
    const { children } = props;

    return (
    <AntdProvider locale={antdLocale} getPopupContainer={antdExternalContainer}>
    <FelaProvider renderer={createRenderer(rendererConfig)}>
    <I18nextProvider i18n={i18n}>
    <div className="antd-local">
    <div id={EXTERNAL_CONTAINER_ID} />
    {children}
    </div>
    </I18nextProvider>
    </FelaProvider>
    </AntdProvider>
    );
    };

    export default ApplicationProvider;

    这目前不起作用,但已在 @diedu 的帮助下得到改进. console.log()我已放入当前未显示的 MockedDragger。如果我放一个 console.log()在组件和 mockedDragger 中,它都会打印组件日志。
    关于如何进行的任何提示?
    我已经看到了 issue并没有帮助。

    最佳答案

    您应该更改的第一件事是您在模拟中所做的返回。您正在返回一个名为 MockedDragger 的新组件,而不是 Dragger .

      return { ...antd, Upload: { ...Upload, Dragger: MockedDragger } };
    接下来是事件触发。根据 this issue您应该使用 RTL 用户事件库并将调用包装在 act
    import userEvent from "@testing-library/user-event";

    ...
    await act(async () => {
    userEvent.upload(uploadDragger, file);
    });
    ...
    最后,由于运行了一些异步代码 you need to flush the pending promises在检查通话之前
      const flushPromises = () => new Promise(setImmediate);
    ...
    await flushPromises();
    expect(onUploadComplete).toHaveBeenCalled()
    这是完整版
    import { render, waitFor } from "@testing-library/react";
    import App from "./App";
    import userEvent from "@testing-library/user-event";
    import { act } from "react-dom/test-utils";
    import { DraggerProps } from "antd/lib/upload";

    jest.mock('antd', () => {
    const antd = jest.requireActual('antd');
    const { Upload } = antd;
    const { Dragger } = Upload;

    const MockedDragger = (props: DraggerProps) => {
    return <Dragger {...props} customRequest={({ onSuccess }) => {
    setTimeout(() => {
    onSuccess('ok');
    }, 0)
    }} />;
    };

    return { ...antd, Upload: { ...Upload, Dragger: MockedDragger } };
    });

    it("completes the image upload", async () => {
    const onUploadComplete = jest.fn();
    const flushPromises = () => new Promise(setImmediate);

    const { getByTestId } = render(
    <App onUploadComplete={onUploadComplete} />
    );

    const file = new File(["(⌐□_□)"], "chucknorris.png", { type: "image/png" });

    const uploadDragger = await waitFor(() => getByTestId("upload-dragger"));
    await act(async () => {
    userEvent.upload(uploadDragger, file);
    });
    await flushPromises();
    expect(onUploadComplete).toHaveBeenCalled();
    });
    不幸的是,我 couldn't set up一个代码框来显示它正在工作,但是如果您遇到任何问题,请告诉我,我可以将代码推送到存储库。

    关于javascript - 如何正确地 mock `antd` Upload Dragger?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67895146/

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