Как сделать снимок шутки после того, как Axios извлек данные в componentDidMount? - PullRequest
0 голосов
/ 29 ноября 2018

Компонент для тестирования

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 голосов
/ 30 ноября 2018

Принятый ответ начал терпеть неудачу на следующий день, не так много 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",
      ...
    },
  ]
}
0 голосов
/ 29 ноября 2018

короче:

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 должен быть послев ожидании объект, который он возвращает, никогда не будет обновлен

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...