小编典典

在axios提取componentDidMount中的数据之后,如何制作一个开玩笑的快照?

reactjs

要测试的组件

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

测试

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()
})

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

在axios完成获取数据后,我不能指望如何运行期望值。

在线上的大多数样本要么使用酶,要么显示具有返回承诺的异步功能的测试。我找不到一个仅使用笑话和渲染组件显示示例的示例。

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


阅读 339

收藏
2020-07-22

共1个答案

小编典典

简而言之:

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

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

应该做的工作

详细信息:除了您模拟的对API数据的调用之外,异步调用仍在进行。因此,我们需要将toMatchSnapshot调用转到微任务队列的末尾。setTimeout(..., 0)setImmediate也可以使用,但是我发现await Promise.resolve()它更好地被识别为“下面的所有内容都将排在队列末尾”

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

2020-07-22