Website-Suche

reactjs - Art des Axios-Mocks mit Jest TypeScript


Ich habe die folgende Methode in einer Klasse:

import axios from 'axios'

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

Dann versuche ich, einen Jest-Test einzurichten, der Folgendes tut:

jest.mock('axios')

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

Das Problem ist, dass, weil ich den Rückgabewert nicht simuliere, ein Fehler für resp.data auftritt, da ich data bei einem null oder undefinierten Objekt aufrufe. Ich habe mindestens 2 Stunden damit verbracht, verschiedene Möglichkeiten auszuprobieren, um dies zum Laufen zu bringen, aber ich kann keinen Weg finden, wie ich axios.get mit einem Rückgabewert simulieren kann.

Die Jest-Dokumentation verwendet JavaScript, daher geben sie dieses Beispiel axios.get.mockResolvedValue(resp), aber ich kann mockResolvedValue nicht aufrufen, weil diese Methode in TypeScript nicht auf axios.get existiert.

Also, wenn du eine andere gute Testing-Bibliothek für React kennst, außer Jest, die diese Dinge einfach für TypeScript macht, teile sie gerne.

Antwort #1

Am Anfang der Datei:

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

Jetzt können Sie es wie gewohnt als Mock verwenden:

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

Antwort #2

Wenn Sie jest.mock mit "no-any" verwenden möchten, versuchen Sie dies:

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)
})

Antwort #3

Ab Jest 24.9.0 funktioniert es so, dass sowohl axios- als auch Jest-Eigenschaften korrekt typisiert werden.

Was wir uns für ein typisiertes Mock wünschen, ist, dass der Typ des gemockten Objekts die Vereinigung des Typs des gemockten Objekts und des Typs von Jest-Mocks enthält. Soweit ich gesehen habe, ermöglicht keiner der aktuellen Antworten dies.

jest.GemockteFunktion

jest.GemockteKlasse

import axios from 'axios';
jest.mock('axios');

const mockedAxios = axios as jest.MockedFunction<typeof axios>;

mockedAxios.mockResolvedValue({ status: 200, data: 'mockResponse' });

// Or:
(mockedAxios.get as jest.MockedFunction<typeof mockedAxios.get>).mockResolvedValue('mockResponse');

Wie Sie sehen können, können Sie entweder manuell das gießen, was Sie benötigen, oder Sie brauchen etwas, um alle Axios-Eigenschaften/-Methoden zu durchlaufen, um alles zu typisieren.

Um das zu tun (tiefgehende Mock-Typen) können Sie jest.mocked() verwenden, eingeführt in Jest 27.4.0

import axios from 'axios';
jest.mock('axios');

const mockedAxios = jest.mocked(axios, true); 

mockedAxios.mockImplementation() // correctly typed
mockedAxios.get.mockImplementation() // also correctly typed

Verwandte Artikel