web-dev-qa-db-fra.com

Impossible d'obtenir le test Jest + TypeScript + Axios

J'ai la méthode suivante dans une classe:

import axios from 'axios'

public async getData() {
   const resp = await axios.get(Endpoints.DATA.URL)
   return resp.data
}

Ensuite, j'essaie de mettre en place un test Jest qui fait ceci:

jest.mock('axios')

it('make api call to get data', () => {
   component.getData()
   expect(axios.get).toHaveBeenCalledWith(Endpoints.DATA.URL)
})

Le problème est que parce que je ne me moque pas de la valeur de retour, cela donne une erreur pour resp.data Parce que j'appelle data sur null ou undefined objet. J'ai passé au moins 2 heures à essayer différentes façons de faire fonctionner cela, mais je ne trouve pas de moyen tel que je puisse me moquer de axios.get Avec une valeur de retour.

La documentation de Jest utilise JavaScript pour donner cet exemple axios.get.mockResolvedValue(resp) mais je ne peux pas appeler mockResolvedValue car cette méthode n'existe pas sur axios.get En TypeScript .

De plus, si vous connaissez une autre bonne bibliothèque de test pour React autre que Jest qui fait ce genre de choses facilement pour TypeScript, n'hésitez pas à partager.

10
Stefan Zhelyazkov

En début de fichier:

import axios from 'axios';
jest.mock('axios');
const mockedAxios = axios as jest.Mocked<typeof axios>;

Vous pouvez maintenant l'utiliser comme une maquette habituelle:

mockedAxios.get.mockRejectedValue('Network error: Something went wrong');
mockedAxios.get.mockResolvedValue({ data: {} });
24
Jan Tumanov

Si vous souhaitez utiliser jest.mock avec "no-any" essaye ça:

import axios, { AxiosStatic } from 'axios'

interface AxiosMock extends AxiosStatic {
  mockResolvedValue: Function
  mockRejectedValue: Function
}

jest.mock('axios')
const mockAxios = axios as AxiosMock

it('make api call to get data', () => {
   // call this first
   mockAxios.mockResolvedValue(yourValue)

   component.getData()
   expect(mockAxios.get).toHaveBeenCalledWith(Endpoints.DATA.URL)
})
4
Adam T. Smith

mais je ne peux pas appeler mockResolvedValue car cette méthode n'existe pas sur axios.get en TypeScript

Vous pouvez utiliser une assertion:

(axios.get as any).mockResolvedValue(resp)
3
basarat

J'ai trouvé une solution intéressante en utilisant la bibliothèque sinonnpm install sinon @types/sinon --save-dev.

Ensuite, le code de test devient:

let component: Component
let axiosStub: SinonStub

beforeAll(() => {
    component = new Component({})
    axiosStub = sinon.stub(axios, 'get')
})

afterAll(() => {
    axiosStub.restore()
})

it('make api call to get data', async () => {
    // set up behavior
    axiosStub.withArgs(Endpoints.DATA.URL).returns({data: []})

    // method under test
    const res = await component.getData()

    // assertions
    expect(res).toEqual([])
})
2
Stefan Zhelyazkov