简体   繁体   English

如何使用 react-testing-library 测试带有动作重定向的表单

[英]How to test a form with action redirection using react-testing-library

I added a search bar using a form and an input to my React app, and I would like to check that it redirects to the right page.我使用表单和我的 React 应用程序的输入添加了一个搜索栏,我想检查它是否重定向到正确的页面。 I am using react-testing-library and react-router-dom.我正在使用 react-testing-library 和 react-router-dom。

Here is my component (simplified):这是我的组件(简化):

const SearchBar = () => (
  <form action={'/search'}>
    <input type="search" name="q" placeholder="search"></input>
  </form>
)

So I wrote this test to check that when I type something in the input, I am redirected to the /search page (which happens in my browser).所以我编写了这个测试来检查当我在输入中输入内容时,我是否被重定向到 /search 页面(这发生在我的浏览器中)。 I followed https://testing-library.com/docs/example-react-router/ and came up with this:我跟着https://testing-library.com/docs/example-react-router/想出了这个:

  it('redirects to search page', async () => {
    const history = createMemoryHistory();
    const header = render(
      <Router history={history}>
        <Switch>
          <Route exact path="/">
            <SearchBar />
          </Route>
          <Route path="/search">
            <div>this is the search page</div>
          </Route>
        </Switch>
      </Router>
    );

    const searchBar = header.getByPlaceholderText('search');
    fireEvent.change(searchBar, { target: { value: 'myQuery' } });
    fireEvent.submit(searchBar);
    expect(screen.getAllByText('this is the search page')).toBeInTheDocument();
  });

Unfortunately it fails with the following error:不幸的是,它失败并出现以下错误:

    TestingLibraryElementError: Unable to find an element with the text: this is the search page. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

    <body>
      <div>
        <form
          action="/search"
        >
          <input
            name="q"
            placeholder="search"
            type="search"
          />
        </form>
      </div>
    </body>

      91 |     fireEvent.change(searchBar, { target: { value: 'myQuery' } });
      92 |     fireEvent.submit(searchBar);
    > 93 |     expect(screen.getAllByText('this is the search page')).toBeInTheDocument();
         |                   ^
      94 |   });
      95 | });
      96 |

      at Object.getElementError (node_modules/@testing-library/dom/dist/config.js:37:19)
      at node_modules/@testing-library/dom/dist/query-helpers.js:92:38
      at getAllByText (node_modules/@testing-library/dom/dist/query-helpers.js:127:15)
      at Object.<anonymous> (src/components/Header/Header.test.tsx:93:19)

From what I understand, I believe that submitting a form does not change the location of my router.据我了解,我相信提交表单不会改变我的路由器的位置。

Is there a way to make the test pass without changing my code?有没有办法在不更改我的代码的情况下通过测试? Or should I forget relying on the action of the form and instead implement a custom onSubmit property that handles the redirection - which I could more easily test?或者我应该忘记依赖formaction ,而是实现一个处理重定向的自定义onSubmit属性 - 我可以更轻松地测试它?

Thanks:)谢谢:)

The form action does not use React Router DOM but instead the native method .表单操作不使用 React Router DOM,而是使用本地方法

<form action={'/search'}>

If you want to use React Router for this, consider using a React onSubmit handler.如果你想为此使用 React Router,请考虑使用 React onSubmit处理程序。 Then your original test should more or less work after integrating with your actual implementation.然后,在与您的实际实现集成后,您的原始测试应该或多或少地工作。

const SearchBar = () => {
  const history = useHistory();

  const handleSubmit = (event) => {
    // Prevent default native behavior of submit
    event.preventDefault();
    // Push the new location to React Router DOM
    history.push("/search");
  };

  return (
    <form onSubmit={handleSubmit}>
      <input type="search" name="q" placeholder="search"></input>
    </form>
  );
};

If you are not looking to change the implementation to use the router, I think a good solution would be to test if the action property is correct and not test native behavior, especially since it's hard to test non-router navigation changes in ( example ) and form submission isn't fully implemented into JSDOM.如果您不希望更改实现以使用路由器,我认为一个好的解决方案是测试action属性是否正确而不测试本机行为,特别是因为很难测试非路由器导航更改(示例)并且表单提交没有完全实现到 JSDOM 中。

it('has form action for the search page', () => {
  const history = createMemoryHistory();
  const header = render(
    <Router history={history}>
      <SearchBar />
    </Router>
  );

  const searchBar = header.getByPlaceholderText('search');
  expect(searchBar).toHaveAttribute('action', '/search');
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用 react-testing-library 和 jest 测试链接 - How to test link using react-testing-library and jest 如何使用 react-testing-library 对数组作为 prop 进行单元测试 - How to unit test an array as a prop using react-testing-library 使用 react-testing-library 在表单中提交时,如何测试已调用 function? - How to test a function has been called when submitted within a form using react-testing-library? 使用 test 和 react-testing-library 测试反应组件 - Test a react component using test and react-testing-library 使用 Redux 和 react-testing-library 测试 React 组件 - Test React Component using Redux and react-testing-library 使用 Jest 和 react-testing-library 测试具有大量输入字段的表单的正确方法是什么? - What is the proper way to test a form with a lot of input fields using Jest and react-testing-library? 如何使用 Jest 和 react-testing-library 测试 react-dropzone? - How to test react-dropzone with Jest and react-testing-library? 如何使用 react-testing-library 测试 react-select - how to test react-select with react-testing-library 如何用 jest 和 react-testing-library 测试 react-toastify - How to test react-toastify with jest and react-testing-library 如何使用带有 msw 和 react-testing-library 的 react-query 测试组件? - How to test components using react-query with msw and react-testing-library?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM