如何在 axios 在 componentDidMount 中获取数据后拍摄开玩笑的快照?

And*_*nga 5 javascript promise reactjs jestjs axios

要测试的组件

class Carousel extends React.Component {
  state = {
    slides: null
  }

  componentDidMount = () => {
    axios.get("https://s3.amazonaws.com/rainfo/slider/data.json").then(res => {
      this.setState({ slides: res.data })
    })
  }

  render() {
    if (!slides) {
      return null
    }

    return (
      <div className="slick-carousel">
        ... markup trancated for bravity
      </div>
    )
  }
}

export default Carousel
Run Code Online (Sandbox Code Playgroud)

测试

import React from "react"
import renderer from "react-test-renderer"
import axios from "axios"
import Carousel from "./Carousel"

const slides = [
  {
    ID: "114",
    REFERENCE_DATE: "2018-07-02",
    ...
  },
  {
    ID: "112",
    REFERENCE_DATE: "2018-07-06",
    ...
  },
  ...
]

jest.mock("axios")

it("", () => {
  axios.get.mockImplementationOnce(() => Promise.resolve({ data: slides }))

  const tree = renderer.create(<Carousel />).toJSON()
  expect(tree).toMatchSnapshot()
})
Run Code Online (Sandbox Code Playgroud)

快照只记录null,因为在执行的那一刻我想state.slides = null

在 axios 完成获取数据后,我无法确定如何运行预期。

大多数在线示例要么使用酶,要么显示带有返回承诺的异步函数的测试。我找不到一个只使用 jest 和渲染组件显示示例的程序。

我尝试制作测试功能async,也使用done回调,但没有运气。

sky*_*yer 3

简而言之:

it("", async () => {
  axios.get.mockImplementationOnce(() => Promise.resolve({ data: slides }))

  const tree = renderer.create(<Carousel />);
  await Promise.resolve();
  expect(tree.toJSON()).toMatchSnapshot()
})
Run Code Online (Sandbox Code Playgroud)

应该做这份工作

详细信息:除了您模拟了对 API 数据的调用之外,数据仍然以异步方式传入。所以我们需要toMatchSnapshot调用微任务队列的末尾。setTimeout(..., 0)或者setImmediate也可以工作,但我发现await Promise.resolve()更好地识别为“下面的所有内容都将排在队列末尾”

[UPD]固定片段:.toJSON必须在等待之后,它返回的对象永远不会被更新