在react jest中测试文件上传

Ang*_*ant 10 javascript reactjs jestjs react-testing-library react-hooks

我有类似的代码(仅保留相关代码)

function App() {
  const [values, setValues] = useState([]);

  async function onUpload(event) {
    if (event?.target.files?.length) {
      const data = await event.target.files[0].text();
      const json = JSON.parse(data);
      setValues(json);
    } else {
      throw new Error('couldnt get files');
    }
  }

  return (
    <div>
      {Boolean(!values.length) && (
        <input data-testid="upInput" accept="application/JSON" type="file" onChange={onUpload} />
      )}
      {Boolean(values.length) && (
        <div data-testid="handler">
          <ValuesHandler values={values} />
        </div>
      )}
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

现在我想测试values用户上传文件时设置是否正确,然后ValuesHandler显示在页面中。

我正在我的 App.test.tsx 中朝这个方向尝试

import user from '@testing-library/user-event';
import someValues from '../somefile.json';
import { render } from '@testing-library/react';

test('should pass', () => {
    const { getByTestId, queryByTestId } = render(<App />);
    const str = JSON.stringify(someValues);
    const blob = new Blob([str]);
    const file = new File([blob], 'values.json', {
        type: 'application/JSON',
    });
    const input = getByTestId('upInput');

    user.upload(input, file);

    const handler = queryByTestId('handler');

    expect(handler).toBeTruthy();
});
Run Code Online (Sandbox Code Playgroud)

由于处理程序为空而失败。

主要怀疑是这条线在开玩笑时不起作用。或者是我处理不当。

    const data = await event.target.files[0].text();
Run Code Online (Sandbox Code Playgroud)

我正在考虑模拟Blob.text直接返回文件内容的方法。但不确定如何。

sli*_*wp2 14

您需要模拟.text()的方法File。只需将模拟.text()方法添加到File.prototype.

\n

例如

\n

App.tsx

\n
import React, { useState } from 'react';\n\nexport function App() {\n  const [values, setValues] = useState([]);\n\n  async function onUpload(event) {\n    if (event?.target.files?.length) {\n      const data = await event.target.files[0].text();\n      const json = JSON.parse(data);\n      setValues(json);\n    } else {\n      throw new Error('couldnt get files');\n    }\n  }\n\n  return (\n    <div>\n      {Boolean(!values.length) && (\n        <input data-testid="upInput" accept="application/JSON" type="file" onChange={onUpload} />\n      )}\n      {Boolean(values.length) && <div data-testid="handler">ValuesHandler</div>}\n    </div>\n  );\n}\n
Run Code Online (Sandbox Code Playgroud)\n

App.test.tsx

\n
import React from 'react';\nimport user from '@testing-library/user-event';\nimport { render, waitFor } from '@testing-library/react';\nimport { App } from './App';\n\nconst someValues = [{ name: 'teresa teng' }];\n\ndescribe('68452480', () => {\n  test('should pass', async () => {\n    const { getByTestId, queryByTestId } = render(<App />);\n    const str = JSON.stringify(someValues);\n    const blob = new Blob([str]);\n    const file = new File([blob], 'values.json', {\n      type: 'application/JSON',\n    });\n    File.prototype.text = jest.fn().mockResolvedValueOnce(str);\n    const input = getByTestId('upInput');\n    user.upload(input, file);\n    await waitFor(() => expect(queryByTestId('handler')).toBeTruthy());\n  });\n});\n
Run Code Online (Sandbox Code Playgroud)\n

测试结果:

\n
 PASS  examples/68452480/App.test.tsx (9.968 s)\n  68452480\n    \xe2\x9c\x93 should pass (53 ms)\n\n----------|---------|----------|---------|---------|-------------------\nFile      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s \n----------|---------|----------|---------|---------|-------------------\nAll files |   88.89 |    78.57 |     100 |   88.89 |                   \n App.tsx  |   88.89 |    78.57 |     100 |   88.89 | 12                \n----------|---------|----------|---------|---------|-------------------\nTest Suites: 1 passed, 1 total\nTests:       1 passed, 1 total\nSnapshots:   0 total\nTime:        10.694 s\n
Run Code Online (Sandbox Code Playgroud)\n