React 测试库查询需要额外的 waitFor 才能成功

for*_*rte 5 async-await reactjs react-router react-redux react-testing-library

我正在使用React 测试库来测试一个组件,该组件通过 redux thunk 获取 componentDidMount 中的数据,并使用 MSW JS 模拟后端。

我的测试本质上是:

  1. 渲染应用程序
  2. 等待组件的“加载状态/旋转器”清除(在所有 redux thunk 内容成功之后),这通过出现带有文本“Create Card”的按钮来表示
  3. 单击“创建卡片”按钮
  4. 等待 redux thunk stuff 成功创建卡片,类似于 #2
  5. 查询组件以获取已创建卡片的证据
const history = createMemoryHistory()
history.push(`/${DECK_ID}`)

const { getByText } = render(
  <Provider store={store}>
    <Router basename="/games" history={history}>
      <App />
    </Router>
  </Provider>
)

await waitFor(() => getByText('Create Card'))
fireEvent.click(getByText('Create Card'))
await waitFor(() => getByText(`Id: ${NEW_CARD_TYPE_ID}`))
Run Code Online (Sandbox Code Playgroud)

奇怪的是,没有找到“创建卡片”:

TestingLibraryElementError: Unable to find an element with the text: Create Card...
...
      124 |     await waitFor(() => getByText('Create Card'))
    > 125 |     fireEvent.click(getByText('Create Card'))
Run Code Online (Sandbox Code Playgroud)

waitFor但当我在它前面添加一个附加(冗余)时,就会发现它,例如:

await waitFor(() => getByText('Create Card'))
await waitFor(() => getByText('Create Card'))
fireEvent.click(getByText('Create Card'))
await waitFor(() => getByText(`Id: ${NEW_CARD_TYPE_ID}`))
Run Code Online (Sandbox Code Playgroud)

...或者将单击操作包装在其自己的 waitFor 中,如下所示:

await waitFor(() => getByText('Create Card'))
await waitFor(() => {
  fireEvent.click(getByText('Create Card'))
})
await waitFor(() => getByText(`Id: ${NEW_CARD_TYPE_ID}`))
Run Code Online (Sandbox Code Playgroud)

更奇怪的是,当我在最后添加断言时,我开始Warning: Encountered two children with the same key从测试中收到错误。我从未调用过两次点击事件,但看起来好像创建了不止一张卡片:

await waitFor(() => getByText('Create Card'))
await waitFor(() => {
  fireEvent.click(getByText('Create Card'))
})
await waitFor(() => getByText(`Id: ${NEW_CARD_TYPE_ID}`))
expect(getByText(`Id: ${NEW_CARD_TYPE_ID}`).textContent).toBe(`Id: ${NEW_CARD_TYPE_ID}`)
Run Code Online (Sandbox Code Playgroud)

任何人都知道为什么会发生这种情况?测试库链接中的示例显示您可以将非异步事件与异步等待混合在一起,所以我不确定发生了什么。

谢谢