redux React-testing-library与react router连接在一起

csbfibhn  于 2023-06-23  发布在  React
关注(0)|答案(1)|浏览(102)

我正在尝试使用React应用程序测试工作流。当所有字段都填写在工作流程步骤中时,用户可以单击“下一步”按钮。此操作在reducer中注册状态并更改URL以转到下一个工作流步骤。
According to the RTL documentation,我使用以下函数将测试中的组件 Package 在存储提供程序和连接的路由器中:

export const renderWithRedux = (ui: JSX.Element, initialState: any = {}, route: string = "/") => {
  // @ts-ignore
  const root = reducer({}, { type: "@@INIT" })
  const state = mergeDeepRight(root, initialState)

  const store = createStoreWithMiddleWare(reducer, state)
  const history = createMemoryHistory({ initialEntries: [route]})

  const Wrapper = ({ children }: any) => (
    <Provider store={store}>
      <ConnectedRouter history={history}>{children}</ConnectedRouter>
    </Provider>
  )
  return {
    ...render(ui, { wrapper: Wrapper }),
    // adding `store` to the returned utilities to allow us
    // to reference it in our tests (just try to avoid using
    // this to test implementation details).
    history,
    store
  }
}

与文档中的不同,我使用的是connected-react-router,而不是react-router-dom,但我看到一些人在web上使用connected-react-router与RTL,所以我不认为问题来自这里。
被测组件被 Package 在一个withRouter函数中,我通过连接的react路由器push函数刷新URL,通过redux connect函数进行调度:

export default withRouter(
  connect<any, any, any>(mapStateToProps, mapDispatchToProps, mergeProps)(View)
)

在生产环境中,一切都运行良好,但是当我在“下一步”按钮上触发click事件时页面不会刷新。下面是我的测试代码(为了让你更容易阅读,我已经填写了所有字段并启用“下一步”按钮):

const {
      container,
      queryByText,
      getAllByPlaceholderText,
      getByText,
      debug,
      getAllByText
    } = renderWithRedux(<Wrapper />, getInitialState(), "/workflow/EXAC")

    await waitForElement(
      () => [getByText("supplierColumnHeader"), getByText("nextButton")],
      { container }
    )

    fireEvent.click(getByText("nextButton"))

    await waitForElement(
      () => [getByText("INTERNAL PARENT"), getByText("EXTERNAL PARENT")],
      { container }
    )

有什么线索吗?

ryoqjall

ryoqjall1#

你的问题中没有足够的信息来弄清楚到底发生了什么,但这是一个很大的线索:
当所有字段都填写在工作流程步骤中时,用户可以单击“下一步”按钮。此操作在reducer中注册状态并更改URL以转到下一个工作流步骤。
单击该按钮可更改URL。为了使其工作,相应的Route需要以功能性的方式在ConnectedRouter中呈现,理想情况下,以与应用程序中使用的相同的方式呈现。基于以下内容,我猜您没有呈现预期页面所需的Route
被测组件被 Package 在一个withRouter函数中,我通过连接的react路由器推函数刷新URL,通过redux连接函数进行调度
据我所知,您的renderWithRedux实用程序正在redux ProviderConnectedRouter中呈现所提供的元素。这意味着您提供的元素:

  • 应该在redux商店的上下文中工作,因此分派操作应该可以工作,假设测试中使用的store在功能上与工作应用程序中使用的store相同。
  • 应该响应路由更改,假设您还呈现了与测试中的URL更改相对应的Route,理想情况下,与工作应用程序中的方式相同。

如果您呈现的内容实际上并没有呈现对应于URL更改的Route,那么DOM中不会发生任何事情。从渲染工具返回的history对象将使用附加条目进行更新,或者JSDOM的window.location将进行更新。
如果需要,您可以Assert对historywindow.location的更改,但这并不理想,因为测试库建议测试用户体验,而不是技术/实现细节:

fireEvent.click(getByText("nextButton"));
expect(history.location.pathname).toBe('/step-two');

相关问题