upload 拖动事件测试无法通过 报错:“TypeError: Cannot read property 'then' of undefined”

来源:10-14 拖动事件怎样测试? - Upload 测试第二部分

阿辉cain

2021-02-14

老师你好我在写upload组件时最后一个drop拖动事件的测试无法通过提示“TypeError: Cannot read property ‘then’ of undefined”。我自行google了也没找到问题所在。只能求助老师了。
错误信息错误信息如上。
测试代码如下基本与老师一致细微不同1.wait改用waitFor。2.class名称是我自定义

import "@testing-library/jest-dom/extend-expect";
import React from "react";
import axios from "axios";
import {
  render,
  RenderResult,
  fireEvent,
  waitFor,
  createEvent,
} from "@testing-library/react";
import { Upload, UploadProps } from "./upload";
jest.mock("../Icon/icon", () => {
  return (props: any) => {
    return <span onClick={props.onClick}>{props.icon}</span>;
  };
});
jest.mock("axios");
const mockedAxios = axios as jest.Mocked<typeof axios>;
const testProps: UploadProps = {
  action: "fakeurl.com",
  onSuccess: jest.fn(),
  onChange: jest.fn(),
  onRemove: jest.fn(),
  drag: true,
};
let wrapper: RenderResult, fileInput: HTMLInputElement, uploadArea: HTMLElement;
const testFile = new File(["xyz"], "test.png", { type: "image/png" });
describe("test upload component", () => {
  beforeEach(() => {
    wrapper = render(<Upload {...testProps}>Click to upload</Upload>);
    fileInput = wrapper.container.querySelector(
      ".egg-file-input"
    ) as HTMLInputElement;
    uploadArea = wrapper.queryByText("Click to upload") as HTMLElement;
  });
  it("upload process should works fine", async () => {
    const { queryByText, getByText } = wrapper;
    mockedAxios.post.mockResolvedValue({ data: "cool" }); //?
    expect(uploadArea).toBeInTheDocument();
    expect(fileInput).not.toBeVisible();
    fireEvent.change(fileInput, { target: { files: [testFile] } });
    expect(queryByText("spinner")).toBeInTheDocument();
    await waitFor(() => {
      expect(queryByText("test.png")).toBeInTheDocument();
    });
    expect(queryByText("check-circle")).toBeInTheDocument();
    expect(testProps.onSuccess).toHaveBeenCalledWith(
      "cool",
      expect.objectContaining({
        raw: testFile,
        status: "success",
        response: "cool",
        name: "test.png",
      })
    );
    expect(testProps.onChange).toHaveBeenCalledWith(
      expect.objectContaining({
        raw: testFile,
        status: "success",
        response: "cool",
        name: "test.png",
      })
    );

    //remove the uploaded file
    expect(queryByText("times")).toBeInTheDocument();
    fireEvent.click(getByText("times"));
    expect(queryByText("test.png")).not.toBeInTheDocument();
    expect(testProps.onRemove).toHaveBeenCalledWith(
      expect.objectContaining({
        raw: testFile,
        status: "success",
        name: "test.png",
      })
    );
  });
  it('drag and drop files should works fine', async () => {
      fireEvent.dragOver(uploadArea);
      expect(uploadArea).toHaveClass('is-dragover');
      fireEvent.dragLeave(uploadArea);
      expect(uploadArea).not.toHaveClass('is-dragover');
      
      const mockDropEvent = createEvent.drop(uploadArea);
      Object.defineProperty(mockDropEvent, "dataTransfer", {
          value: {
              files: [testFile]
          }
      });
      
	  // test 报错处
      fireEvent(uploadArea, mockDropEvent);
      await waitFor(() => {
        expect(wrapper.queryByText('test.png')).toBeInTheDocument()
      })
      expect(testProps.onSuccess).toHaveBeenCalledWith('cool', expect.objectContaining({
        raw: testFile,
        status: 'success',
        response: 'cool',
        name: 'test.png'
      }))
  });
  
});

写回答

1回答

张轩

2021-02-15

同学你好 报错说明 axios 没有模拟到位,将 

mockedAxios.post.mockResolvedValue({ data: "cool" });

这行 也要放到第三个用例中去,试试

1
2
张轩
回复
阿辉cain
有可能是版本问题 我当时那样写是不太准确的做法 最好是将这个模拟放置到 beforeEach 中,在每个 case 开始之前模拟
2021-02-17
共2条回复

React18+TS高仿AntD从零到一打造组件库

设计,开发,测试,发布再到 CI/CD,从0到1造轮子

2122 学习 · 959 问题

查看课程