React-testing-library 与连接的反应路由器一起

ViG*_*rad 9 reactjs redux react-redux react-testing-library connected-react-router

我正在尝试使用 React 应用程序测试工作流。当所有字段都填满工作流程步骤时,用户可以单击“下一步”按钮。此操作在减速器中注册状态并更改 URL 以转到下一个工作流程步骤。

根据 RTL 文档,我使用此功能将测试中的组件包装在商店提供程序和连接的路由器中:

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
  }
}
Run Code Online (Sandbox Code Playgroud)

与文档不同,我使用的是connected-react-router,而不是react-router-dom,但我connected-react-router在网上看到有些人使用RTL,所以我认为问题不是来自这里。

被测组件被封装在一个withRouter函数中,我通过连接的 react 路由push函数刷新 URL ,通过 reduxconnect函数调度:

export default withRouter(
  connect<any, any, any>(mapStateToProps, mapDispatchToProps, mergeProps)(View)
)
Run Code Online (Sandbox Code Playgroud)

在生产中一切正常,但是当我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 }
    )
Run Code Online (Sandbox Code Playgroud)

关于这里出了什么问题的任何线索?

Ken*_*ory 0

您的问题中没有足够的信息来弄清楚到底发生了什么,但这是一个很大的线索:

当所有字段都填满工作流程步骤时,用户可以单击“下一步”按钮。此操作在减速器中注册状态并更改 URL 以转到下一个工作流程步骤。

单击该按钮会更改 URL。为此,需要以功能方式(理想情况下)以与应用程序中使用的相同方式Route呈现相应的内容。ConnectedRouter根据以下内容,我猜测您没有渲染Route预期页面所需的内容:

被测试的组件被包装在 withRouter 函数中,我通过连接的 React 路由器推送函数刷新 URL,通过 redux connect 函数进行调度

据我所知,您的renderWithRedux实用程序正在 reduxProviderConnectedRouter. 这意味着您提供的元素:

  • 应该在 redux 存储的上下文中工作,因此调度操作应该可以工作,假设store您的测试中使用的操作在功能上与工作应用程序中使用的操作相同。
  • 应该响应路由更改,假设您还渲染了Route与测试中的 URL 更改相对应的内容,最好与工作应用程序中的方式相同。

如果您正在渲染的内容实际上并未渲染Route与您的 URL 更改相对应的内容,则 DOM 中不会发生任何事情。从渲染实用程序返回的对象history将使用附加条目进行更新,或者 JSDOMwindow.location将进行更新。

您可以断言更改historywindow.location如果需要,但这不太理想,因为测试库建议测试用户体验,而不是技术/实现细节:

fireEvent.click(getByText("nextButton"));
expect(history.location.pathname).toBe('/step-two');
Run Code Online (Sandbox Code Playgroud)