簡體   English   中英

如何在 axios 在 componentDidMount 中獲取數據后拍攝開玩笑的快照?

[英]How to take a jest snapshot after axios fetched data in componentDidMount?

要測試的組件

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 完成獲取數據后,我無法確定如何運行預期。

大多數在線示例要么使用酶,要么顯示帶有返回承諾的異步函數的測試。 我找不到一個只使用 jest 和渲染組件顯示示例的程序。

我嘗試使測試函數async ,也使用done回調,但沒有運氣。

簡而言之:

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()await Promise.resolve()識別為“下面的所有內容都將進入隊列末尾”

[UPD] 固定片段: .toJSON必須在等待之后,它返回的對象永遠不會更新

第二天,接受的答案開始失敗。 經過一些調整后,這似乎有效:

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",
      ...
    },
  ]
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM