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

时间:2018-11-29 19:02:04

标签: javascript reactjs promise axios jestjs

要测试的组件

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,但是没有运气。

2 个答案:

答案 0 :(得分:2)

简而言之:

reset
set xdata time
set timefmt '%Y-%m-%dT%H:%M:%SZ'
set xrange ["2018-04-16":"2018-04-14"]
plot 'dat' using 1:0

应该做的事

详细信息:除了您模拟了对API数据的调用外,它仍然以异步方式进行。因此,我们需要it("", async () => { axios.get.mockImplementationOnce(() => Promise.resolve({ data: slides })) const tree = renderer.create(<Carousel />); await Promise.resolve(); expect(tree.toJSON()).toMatchSnapshot() }) 调用转到微任务队列的末尾。 toMatchSnapshotsetTimeout(..., 0)也可以使用,但我发现setImmediate可以更好地识别,因为“下面的所有内容都将排在队列末尾”

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

答案 1 :(得分:0)

第二天开始接受的答案开始失败,没有太多的js,请专家来理解原因。经过一些调整后,这似乎奏效了

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

jest.mock("axios")
const slides = sampleApiResponse()
const mockedAxiosGet = new Promise(() => ({ data: slides }))
axios.get.mockImplementation(() => mockedAxiosGet)

// eventhough axios.get was mocked, data still comes anychrnonously,
// so during first pass state.slides will remain null
it("returns null initally", () => {
  const tree = renderer.create(<Carousel />).toJSON()
  expect(tree).toMatchSnapshot()
})

it("uses fetched data to render carousel", () => {
  const tree = renderer.create(<Carousel />)
  mockedAxiosGet.then(() => {
    expect(tree.toJSON()).toMatchSnapshot()
  })
})

function sampleApiResponse() {
  return [
    {
      ID: "114",
      REFERENCE_DATE: "2018-07-02",
      ...
    },
    {
      ID: "114",
      REFERENCE_DATE: "2018-07-02",
      ...
    },
  ]
}