首页 > 解决方案 > 使用反应测试库和触发函数模拟子组件

问题描述

所以我想在容器组件上测试方法“handleUpdate”。在该容器组件中有一个表单组件。

./MyContainer.jsx

const MyContainer = ({ handleUpdate }) => (
  <MyForm onSubmit={handleUpdate} />
);

./MyForm.jsx

const MyForm = ({ onSubmit }) => {
  const [error, setError] = useState();
  const [nameValue, setNameValue] = useState();

  handleChange(event) {
    setNameValue(event.target.value);
  }
  
  handleSubmit(event) {
    event.preventDefault();
    if (!nameValue) { setError("Name is required"); }
    onSubmit(nameValue);
  }

  return (
    <form onSubmit={handleSubmit}>
      <label htmlFor="nameInput">Name: </label>
      <input type="text" name="name" onChange={handleChange} id="nameInput" />
      {error && <p>{error}</p>}
      <button name="save button" type="submit">Submit</button>
    </form>
  );
};

此表单组件针对用户可以与之进行的交互进行单独测试:

./MyForm.test.js

const mockSubmit = jest.fn();
function setup() {
  render(<MyForm onSubmit={mockSubmit} />);
}

it('has a required field', () => {
  setup();

  userEvent.click(screen.getByRole('button', { name: 'save button' }));

  expect(screen.getByText('Name is required.'));
});

it('saves', () => {
  setup();

  // make sure name has a value
  userEvent.type(screen.getByLabelText(/^name$/i), 'John');

  userEvent.click(screen.getByRole('button', { name: 'save button' }));
  expect(mockSubmit).toHaveBeenCalled();
});

现在我想测试表单组件何时触发提交,容器组件中触发了“handleUpdate”。但我不想必须设置输入值等才能保存表单:

./MyContainer.test.js

const mockUpdate = jest.fn();
function setup() {
  render(<MyContainer handleUpdate={mockUpdate} />);
}

it('handles an update', () => {
  setup();

  // problem is here
  //
  // the input name is already tested in ./MyForm.test.js
  // so I don't want to have to do this again...
  userEvent.type(screen.getByLabelText(/^name$/i'), 'John');

  userEvent.click(screen.getByRole('button', { name: 'save button' }));

  expect(mockUpdate).toHaveBeenCalled();
});

所以理想情况下,我想模拟 MyForm 组件并在我的测试中手动触发 onSubmit。

你会怎么做?

尝试以下操作:

我在考虑使用jest.mock('./MyForm.test.js')

jest.mock('./MyForm.js', () => () => {
  return <p>test</p>;
});

const mockUpdate = jest.fn();
function setup() {
  render(<MyContainer handleUpdate={mockUpdate} />);
}

it('handles an update', () => {
  setup();

  screen.debug(); // <- this shows that MyForm is now replaced with "<p>test</p>"
  // how to trigger the handleUpdate from this?

  userEvent.click(screen.getByRole('button', { name: 'save button' }));

  expect(mockUpdate).toHaveBeenCalled();
});

但是我怎样才能触发“handleUpdate”呢?

标签: reactjsunit-testingreact-testing-library

解决方案


推荐阅读