如何基于文件读取器发出的事件测试React组件

时间:2019-07-10 18:06:22

标签: reactjs unit-testing filereader react-hooks react-testing-library

我有一个基于Dropzone react组件(https://github.com/react-dropzone/react-dropzone)的React File组件。该文件读取器在将文件拖放到FileReader的input元素上时会调用一个回调react钩子,如下所示:

import React, { useCallback } from 'react';
import PropTypes from 'prop-types';
import { useDropzone } from 'react-dropzone';

function FilePicker(props) {
  const { fileName, setFile, setFileName } = props;

  const onDrop = useCallback((acceptedFiles) => {
    const reader = new FileReader();

    reader.onload = () => {
      const binaryFile = reader.result;
      setFile(binaryFile);
    };

    acceptedFiles.forEach((file) => {
      setFileName(file.name);
      return reader.readAsBinaryString(file);
    });
  }, [setFile, setFileName]);
  const { getRootProps, getInputProps } = useDropzone({ onDrop });

  return (
    <div data-testid="file-picker" id="file-picker" {...getRootProps()}>
      <div className="container-fluid inherit-height">
        <input data-testid="file-picker-input" {...getInputProps()} />
        <div className="row align-content-center inherit-height">
          <p data-testid={fileName} className="text-center" id="file-picker-title">
            {fileName !== '' ? fileName : 'Drag n drop a file here, or click to select file' }
          </p>
        </div>
      </div>
    </div>
  );
}

FilePicker.propTypes = {
  fileName: PropTypes.string.isRequired,
  setFile: PropTypes.func.isRequired,
  setFileName: PropTypes.func.isRequired,
};

export default FilePicker;

现在,我正在尝试以一种可以检查函数setFile和setFileName是否已正确调用的方式来测试此组件。我的测试文件如下所示:

import React from 'react';
import { render, cleanup, fireEvent, act } from '@testing-library/react';
import 'jest-dom/extend-expect';
import FileReader from './__mocks__/FileReader';
import FilePicker from './FilePicker';

afterEach(cleanup);

describe('React Use S3 Demo', () => {
  it('should render file picker', () => {
    const mockedFileName = '';
    const mockedSetFile = jest.fn();
    const mockedSetFileName = jest.fn();

    const { rerender, getByTestId, debug } = render(
      <FilePicker
        fileName={mockedFileName}
        setFile={mockedSetFile}
        setFileName={mockedSetFileName}
      />,
    );

    const filePicker = getByTestId('file-picker-input');

    act(() => {
      fireEvent.drop(filePicker, {
        target: {
          files: [new File(['(⌐□_□)'], 'chucknorris.png', { type: 'image/png' })],
        },
      });
    });

    expect(mockedSetFileName).toHaveBeenCalled();
    expect(mockedSetFile).toHaveBeenCalled();
  });
});

乍看之下,这似乎可行,但实际上并非如此,因为FileReader组件似乎并未调用作为支持而下降的两个函数。我试过使用'@ testing-library / react'中的rerender函数,但这似乎也无济于事。您将如何测试FileReader,以便在调用setFile和setFileName函数时验证您的测试?

谢谢!

0 个答案:

没有答案