首页 > 解决方案 > 反应路由器测试从非家庭开始

问题描述

我正在测试我的 App 组件,在第一个测试中,它从家里开始,我必须单击饮料预览才能获得食谱。然而,在下一个测试中,应该遵循相同的步骤来获得配方,我得到了错误

无法通过以下方式找到元素:[data-testid="drink-preview"]

我开始意识到这是因为它似乎已经从配方开始,所以它没有呈现主页以供它点击饮料预览。只是为了确保我复制粘贴了与家中完全相同的测试 -> 单击“drink-preview” -> 食谱,并且肯定是第二次,它有同样的问题。错误日志显示它正在直接渲染配方而不是主页,因此无法找到饮料预览以单击它。

test('should contain default texts in recipe -HOW TO MIX etc.', () => {
  
  const { container, getAllByTestId, getByTestId } = renderWithRouterRedux(<App />)
  
  fireEvent.click(getAllByTestId('drink-preview')[0])
  
  expect(container).toHaveTextContent('HOW TO MIX')
  expect(container).toHaveTextContent('Glass')
  expect(container).toHaveTextContent('Method')
  expect(container).toHaveTextContent('Garnish')
})
export const renderWithRouterRedux= (component, { initialState, store = createStore(reducer, initialState) } = {}) => {
  const history = createMemoryHistory()
  return {
    ...render(<Provider store={store}>
      <Router history={history}>
        {component}
      </Router>
    </Provider>),
    store,
  }
}

为什么会出现这种行为?

标签: reactjsunit-testingreact-routerjestjsreact-testing-library

解决方案


问题似乎是在我的测试中,我在两个级别的 BrowserRouter 中渲染了我的 {component} 应用程序;测试级别并作为 App 组件的第一个子级。

原来的

//App component
<div className="App" data-testid="app">
 <BrowserRouter>
      <Switch>
        <Route path="/">
          <SomeComponent/>
        </Route>
      </Switch>
    </BrowserRouter>
</div>

//index.js
ReactDOM.render(
  <Provider store={store}>
      <App />
  </Provider>,
  document.getElementById('root')
)

在已经拥有 BrowserRouter 的 App 组件之上,我再次在路由器中的测试文件中渲染,这是不必要的。

解决方案是将 移动到 index.js 以便它在浏览器中呈现时包装。然后还允许我在测试中使用 a 来安全地包装应用程序组件

解决方案

//App component
<div className="App" data-testid="app">
    <Switch>
        <Route path="/">
          <SomeComponent/>
        </Route>
    </Switch>
</div>

//index.js
ReactDOM.render(
  <Provider store={store}>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </Provider>,
  document.getElementById('root')
)

这个关于测试 React-Router 的 Rithm School 视频给了我尤里卡


推荐阅读