如何使用单元测试覆盖Promise.all(...)语句

时间:2019-09-02 14:55:33

标签: reactjs jestjs react-testing-library

我无法编写在componentDidMount方法的setTimeout()块中运行的异步函数(loadMessages())中包含Promise.all()语句的测试。

在componentDidMount中有setTimeout回调函数中调用的this.loadMessages()函数,为了完成测试,我需要执行loadMessages()。

componentDidMount() {
    const { conversationId } = this.state
    const POLLING_INTERVAL = 3000

    if (conversationId) {
      setTimeout(() => this.loadMessages(), 0)
      this.timer = setInterval(() => this.loadMessages(), POLLING_INTERVAL)
    } else {
      this.setState({ loading: false })
    }
  }

我通过

解决了setTimeout回调

await new Promise(resolve =>
      setTimeout(() => {
        resolve()
      }, 3000)
    )

并且解决了函数调用,但是当开始执行函数时,报告的覆盖范围是说Promise.all没有被覆盖,函数本身看起来像:


async loadMessages() {
    const { messages, conversationId, errors } = this.state
    let messagesWithAuthors

    // initial load
    if (messages.length === 0) {
      try {
        let initialMessages = await runtime.dais.communication.auto.getMessagesByConversationId(
          conversationId
        )

        const messageAuthors = await Promise.all(
          initialMessages.map(async message =>
            //runtime.dais.orgService.auto.getPersonById(message.sender.id)
            runtime.dais.organization.auto.getPersonById(message.sender.id)
          )
        )

        messagesWithAuthors = initialMessages.map((message, i) => ({
          ...message,
          author: messageAuthors[i],
        }))

        this.setState({
          messages: messagesWithAuthors,
          messageAuthors,
          loading: false,
        })
      } catch (error) {
        this.setState({ errors: [...errors, error], hasErrors: true, modalOpen: true })
      }
    } else {
      let updatedMessages = await runtime.dais.communication.auto.getMessagesByConversationId(
        conversationId
      )
      this.checkIfNeedUpdate(updatedMessages)
    }
  }

是否有某种方法可以将Promise.all()返回的值模拟到messageAuthors变量中? 我正在使用@ testing-library / react进行测试,我的测试看起来像这样

 it('ensure that we have chat window shown if we have conversation as a prop', async () => {
    const queries = render(
      <CommWidget runtime={runtime} conversationId="fe3d52fc-ffb3-482a-aedf-79000645ca70" />
    )
    await new Promise(resolve =>
      setTimeout(() => {
        resolve()
      }, 3000)
    )

    const commWidget = queries.container.querySelector(
      '.ui-comm-widget .ui.segments.comm-widget #chat-window'
    )

    expect(commWidget).toBeInstanceOf(HTMLDivElement)
  })

1 个答案:

答案 0 :(得分:0)

请不要在测试中设置超时,这是一种反模式。诺言解决后会发生什么?页面会改变吗?如果是这样,请等待更改出现。有关测试异步方法的介绍,请参见this article