Jest асинхронная функция - PullRequest
       34

Jest асинхронная функция

0 голосов
/ 31 декабря 2018

Я новичок в шутке / энзиме и пытаюсь проверить функцию.Тест пытается проверить, что getData() устанавливает массив, возвращаемый в состоянии.

Вот как это выглядит:

getData () {
  axios.get('http://localhost:8080/targeting-data').then(response => {
    this.setState({
      targetingData: response.data,
      load: true
    })
  })
}

componentDidMount () {
  this.interval = setTimeout(() => {
    this.getData()
  }, 3000)
}

Мой первый тест:

import FormWrapper from './../containers/FormWrapper/FormWrapper'

const mockGetData = jest.spyOn(FormWrapper.prototype, 'getData')

it('testing', () => {
  mockGetData()
  expect(formWrapper.state().targetingData).toHaveLength(8)
})

И я получил ошибки:

expect(received).toHaveLength(length)

Expected value to have length:
  8
Received:
  []
received.length:
  0

Мой второй тест:

it('getDataFunc', (done) => {
  mockGetData().then(res => {
    expect(res).toHaveLength(8)
    done()
  })
})

И я получил ошибки:

TypeError: Cannot read property 'then' of undefined

(node:6302) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'setState' of undefined
(node:6302) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 4)

Я запутался в том, как проверитьэто я буду рад любым предложениям.Спасибо

1 Ответ

0 голосов
/ 01 января 2019

Вы можете использовать подход async / await , чтобы проверить вашу функцию getData как она есть async, но сначала вам нужно смоделировать метод axios get, потому что вы не хотите включатьвнешний вызов API в вашем тесте, вместо этого просто смоделируйте его ответ:

import React from 'react';
import axios from 'axios';
import {shallow, mount} from "enzyme";
import FormWrapper from './../containers/FormWrapper/FormWrapper'

jest.mock('axios'); // for mocking axios

it('test', async () => {
    const wrapper = shallow(<FormWrapper />); // I'm using shallow render, you could use mount if you want to
    const instance = wrapper.instance(); // get an instance in order to call getData() directly
    // mock axios get with a response
    axios.get.mockImplementation(() => Promise.resolve([
        {
            id: 1,
            val: 'val1'
        },
        {
            id: 2,
            val: 'val2'
        }
    ]));
    await instance.getData();
    expect(wrapper.state().targetingData).toHaveLength(2); // this is the length of the mocked response I have added here
});

Есть кое-что, что я хотел бы отметить здесь об этой функции.По моему мнению, функция getData(), которую вы пытаетесь протестировать, на самом деле не является хорошим объектом для тестирования, поскольку она не содержит никакой написанной вами логики.

Она получает некоторые данные из API (который не являетсячем-то, что у вас есть), тогда он использует this.setState для установки состояния (и вы не хотите проверять поведение React, выполняя setState для обновления вашего состояния).

В случае, если вы хотите иметь state заполняется некоторыми данными, чтобы использовать их для тестирования других функций в компоненте, тогда я предлагаю вам установить его вручную следующим образом:

const wrapper = shallow(<FormWrapper />);
wrapper.setState({
    targetingData: {...}
});

, чтобы вы больше сосредоточились на функциях и частях кода, содержащих большелогику вы написали сами.

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