首页 > 解决方案 > 反应重定向单元测试未呈现预期的dom

问题描述

我正在尝试单元测试(使用 React 测试库)我的重定向按预期发生并且实际发生在实践中,但是在我的测试中似乎没有实际呈现任何东西......


应用程序.js

// I set up a test route to get this working before I point it at the real page

<Route exact path={`${process.env.PUBLIC_URL}/blah`} render={() => (
    <div data-testid="my-test">THIS IS A TEST</div>
)}/>

我的组件.jsx

// I have forced this component to do the redirect for testing purposes
...
return (
    <BrowserRouter>
        <Redirect to={`${process.env.PUBLIC_URL}/blah`} />
    </BrowserRouter>
);

我发现不包裹我<Redirect><BrowserRouter>产生错误

You should not use <Redirect> outside a <Router>

测试.js

it('should redirect', async () => {
    const state = configState(); // <---- Set custom initial state of component
    const store = configureStore();

    rendered = render(
        <Provider store={store(state)}>
            <ForgotPasswordNewPasswordJourney />
        </Provider>
    );

    // check that the content changed to the new page
    expect(rendered.getByText("THIS IS A TEST")).toBeTruthy();
});

这个测试的结果是:

TestingLibraryElementError: Unable to find an element with the text: THIS IS A TEST. 
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 />
   <div />
</body>

      116 | 
      117 |         // check that the content changed to the new page
    > 118 |         expect(rendered.getByText("THIS IS A TEST")).toBeTruthy();
          |                         ^
      119 |     });
      120 | 
      121 | 

注意:当我用以下方法包装我的测试渲染时,我也会收到此错误<BrowserRouter>

<Provider store={store(state)}>
    <BrowserRouter>
         <ForgotPasswordNewPasswordJourney />
    </BrowserRouter>
</Provider>

特殊的行为...... 我确实在网上读到这可能是一个异步/等待问题,因为重定向需要时间来执行等等。所以我看到使用waitFor可能是一个选项,并且在执行时:

waitFor(() => expect(rendered.getByText("THIS IS A TEST")).toBeTruthy());

这实际上让我惊讶地通过了测试......但是,如果我在getByText字段中放置一个无意义的字符串,这也将通过我的测试......所以看起来这也不是答案。

我究竟做错了什么?

标签: javascriptreactjsunit-testingtestingreact-testing-library

解决方案


我在查看这篇文章后设法解决了这个问题,我可以看到我的错误。

看来我需要在我的内部添加一个<Router和作为一种模拟路线才能通过。<Route<Provider>

const myStore = configureStore();
const history = createMemoryHistory();
history.push(fromUrl);

<Provider store={myStore(store)}>
   <Router history={myHistory}>
       <Component {...props} />
       <Route path={toUrl}>
           <div data-testid="test">THIS IS A TEST</div>
       </Route>
   </Router>
</Provider>

然后我可以开始看到测试中呈现的东西。

也可以实际渲染组件而不是测试元素:

<Route path={toUrl}> render={() => <RedirectComponent {...props} />}

但是,如果这是使用 Redux,我们还需要在其<Provider>周围添加 and store 包装器。


推荐阅读