TypeScript - wie kann ich einen Unit-Test von einem axios.create-Mock mit Vitest durchführen?
Ich lerne Unit-Testing in Vue mit TypeScript und ich möchte diese Funktion testen:
const getCLients =async (): Promise<Client[]> => {
const {data} = await clientsApi.get('/clients')
return data
}
Aber ich bekam einen Fehler wegen der clientsApi. Meine Clients-API ist eine Axios-Instanz und sieht so aus:
import axios from 'axios'
const clientsApi = axios.create({
baseURL:import.meta.env.VITE_API_URL
})
export default clientsApi
Mein Fehler ist dieser:
TypeError: Eigenschaften von undefined können nicht gelesen werden (lese 'get') ❯ getCLients ../src/clients/composables/useClients.ts:14:41
14| const {data}=await clientsApi.get('/clients')
In meinen Tests habe ich das Axios-Mock gemacht:
vi.mock('axios')
const mockedAxios = axios as jest.Mocked<typeof axios>;
mockedAxios.get.mockResolvedValue({
data: mockClients,
})
Ich nahm an, dass ich ein Mock von axios.create erstellen müsste, aber ich habe es auf viele Arten versucht und bekomme immer denselben Typfehler. Ich brauche deine Hilfe, wie kann man das lösen?
Antwort #1
Nicht sicher, ob ich auf dem richtigen Weg bin, da es bei mir einfach funktioniert. Ich mache vi.mock('axios') und habe Error: spyOn konnte kein Objekt finden, auf das es spionieren könnte. Also mache ich vi.mock(den Pfad zur Instanz) und mache vi.spyOn(die axios-Instanz, 'get').mockResolvedValue und in deinem Fall könnte es clientsApi sein.
Antwort #2
Wenn Sie beispielsweise in Ihrem Code axios.create() verwenden, um eine AxiosInstance zu erstellen, können Sie diese Funktionalität in Ihrer Vitest-Testdatei wie folgt simulieren:
const mocks = vi.hoisted(() => ({
get: vi.fn(),
post: vi.fn(),
// and any other request type you want to mock
}));
vi.mock('axios', async(importActual) => {
const actual = await importActual<typeof import ('axios')>();
const mockAxios = {
default: {
...actual.default,
create: vi.fn(() => ({
...actual.default.create(),
get: mocks.get,
post: mocks.post,
})),
},
};
return mockAxios;
});Zunächst richten wir das mocks-Objekt ein, das die get- und post-Funktionen enthält, die wir mocken möchten. Mit vi.hoisted() stellen wir sicher, dass diese gemockten Funktionen hochgezogen werden (d. h. an den Anfang des Scope verschoben), wodurch wir sie innerhalb unserer vi.mock()-Funktion referenzieren können.
Dann mocken wir das gesamte axios-Modul mit vi.mock(). Um die bestehende Funktionalität, die wir nicht mocken möchten, beizubehalten, verwenden wir importActual, um das echte axios-Modul zu importieren. Anschließend geben wir die Teile an, die wir mocken möchten, nämlich die create-Funktion und die get/post-Funktionen.
Mit diesen Mocks können wir nun unsere gemockten get- und post-Methoden überwachen. Hier ist ein Beispiel, wie man es macht:
it('should call axios.get', async() => {
mocks.get.mockResolvedValueOnce({
data: {},
});
await clientsApi.getCLients();
expect(mocks.get).toHaveBeenCalled(); // should return true
});Im Testfall mocken wir einen aufgelösten Wert für unsere get-Methode und rufen die Funktion auf, die wir testen möchten (in diesem Fall clientsApi.getCLients()). Anschließend prüfen wir, ob unsere gemockte get-Funktion mit expect().toHaveBeenCalled() aufgerufen wurde.
Dieses Setup bietet eine kontrollierte Umgebung, um die Interaktionen mit der Axios-Bibliothek in unserem Code zu testen.
