如何使用 FormData 发送 event.target 来模拟函数

Max*_*ynn 5 reactjs jestjs enzyme

我正在尝试模拟一个使用FormData. 该函数接受依赖于目标中某些内容的事件参数。

  buildFormData: (event) => {
    event.preventDefault();
    const { target } = event;
    const data = new FormData(target);

    if (target.querySelectorAll('.ant-select').length) {
      const selectTags = target.querySelectorAll('.ant-select');

      selectTags.forEach((selectTag) => {
        const value = selectTag.querySelector('.ant-select-selection-selected-value').getAttribute('title');
        const property = selectTag.getAttribute('id');
        data.append(property, value);
      });
    }

    const getDataObject = {};

    for (var pair of data.entries()) {
      // Ensures that the data from the forms have a value
      if (pair[1]) {
        getDataObject[pair[0]] = pair[1];
      }
    }

    return getDataObject;
  }
Run Code Online (Sandbox Code Playgroud)

我想确保该函数从模拟表单返回一个值对象。

我试过通过:

const event = {
  target: {}
}
Run Code Online (Sandbox Code Playgroud)

但很快就意识到目标是空的。

有没有一种简单的方法来模拟这些数据,以便我从上面的函数中获得预期的回报?

sli*_*wp2 3

这是解决方案,您可以手动模拟FormData和形成:event

\n\n

index.tsx:

\n\n
import React, { Component } from \'react\';\nimport console = require(\'console\');\n\nclass XComponent extends Component {\n  constructor(props) {\n    super(props);\n    this.buildFormData = this.buildFormData.bind(this);\n  }\n  public buildFormData(event) {\n    event.preventDefault();\n    const { target } = event;\n    const data: any = new FormData(target);\n\n    if (target.querySelectorAll(\'.ant-select\').length) {\n      const selectTags = target.querySelectorAll(\'.ant-select\');\n\n      selectTags.forEach(selectTag => {\n        const value = selectTag.querySelector(\'.ant-select-selection-selected-value\').getAttribute(\'title\');\n        const property = selectTag.getAttribute(\'id\');\n        data.append(property, value);\n      });\n    }\n\n    const getDataObject = {};\n    for (const pair of data.entries()) {\n      // Ensures that the data from the forms have a value\n      if (pair[1]) {\n        getDataObject[pair[0]] = pair[1];\n      }\n    }\n\n    return getDataObject;\n  }\n\n  public render() {\n    return (\n      <div>\n        <form onSubmit={this.buildFormData}></form>\n      </div>\n    );\n  }\n}\n\nexport default XComponent;\n
Run Code Online (Sandbox Code Playgroud)\n\n

index.spec.tsx:

\n\n
import React from \'react\';\nimport XComponent from \'./\';\nimport { shallow } from \'enzyme\';\n\nconst FormDataMock = {\n  append: jest.fn(),\n  entries: jest.fn()\n};\n\ndescribe(\'XComponent\', () => {\n  const mockedFormEvent = { target: { querySelectorAll: jest.fn() }, preventDefault: jest.fn() };\n\n  beforeEach(() => {\n    (global as any).FormData = jest.fn(() => FormDataMock);\n  });\n\n  afterEach(() => {\n    jest.resetAllMocks();\n  });\n\n  it(\'should build form data correctly without select tags\', () => {\n    mockedFormEvent.target.querySelectorAll.mockReturnValueOnce([]);\n    FormDataMock.entries.mockReturnValueOnce([[\'k1\', \'v1\'], [\'k2\', \'v2\'], [\'k3\', \'v3\']]);\n    const wrapper = shallow(<XComponent></XComponent>);\n    const actualValue = (wrapper.instance() as any).buildFormData(mockedFormEvent);\n    expect(actualValue).toEqual({ k1: \'v1\', k2: \'v2\', k3: \'v3\' });\n    expect(mockedFormEvent.preventDefault).toBeCalledTimes(1);\n    expect(mockedFormEvent.target.querySelectorAll).toBeCalledWith(\'.ant-select\');\n    expect((global as any).FormData).toBeCalledTimes(1);\n  });\n\n  it(\'should build form data correctly with select tags\', () => {\n    const mockedSelectTag = { querySelector: jest.fn().mockReturnThis(), getAttribute: jest.fn() };\n    const mockedSelectTags = [mockedSelectTag];\n    (mockedSelectTag.querySelector().getAttribute as any).mockReturnValueOnce(\'value\').mockReturnValueOnce(\'property\');\n    mockedFormEvent.target.querySelectorAll.mockReturnValue(mockedSelectTags);\n    FormDataMock.entries.mockReturnValueOnce([[\'k1\', \'v1\'], [\'k2\', \'v2\'], [\'k3\', \'v3\']]);\n    const wrapper = shallow(<XComponent></XComponent>);\n    const actualValue = (wrapper.instance() as any).buildFormData(mockedFormEvent);\n    expect((global as any).FormData).toBeCalledTimes(1);\n    expect(actualValue).toEqual({ k1: \'v1\', k2: \'v2\', k3: \'v3\' });\n    expect(FormDataMock.append).toBeCalledWith(\'property\', \'value\');\n    expect(mockedFormEvent.preventDefault).toBeCalledTimes(1);\n    expect(mockedFormEvent.target.querySelectorAll).toBeCalledWith(\'.ant-select\');\n  });\n});\n
Run Code Online (Sandbox Code Playgroud)\n\n

带有覆盖率报告的单元测试结果:

\n\n
 PASS  src/stackoverflow/58136380/index.spec.tsx (5.601s)\n  XComponent\n    \xe2\x9c\x93 should build form data correctly without select tags (11ms)\n    \xe2\x9c\x93 should build form data correctly with select tags (3ms)\n\n-----------|----------|----------|----------|----------|-------------------|\nFile       |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |\n-----------|----------|----------|----------|----------|-------------------|\nAll files  |      100 |    83.33 |      100 |      100 |                   |\n index.tsx |      100 |    83.33 |      100 |      100 |                27 |\n-----------|----------|----------|----------|----------|-------------------|\nTest Suites: 1 passed, 1 total\nTests:       2 passed, 2 total\nSnapshots:   0 total\nTime:        10.438s, estimated 15s\n
Run Code Online (Sandbox Code Playgroud)\n\n

源代码:https ://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/58136380

\n