Zephyrnet-logotyp

Använda mocks för att testa i JavaScript med Jest

Datum:

Beskrivning

Jest är ett populärt testramverk med öppen källkod för JavaScript. Vi kan använda Jest för att skapa hån i vårt test - objekt som ersätter riktiga objekt i vår kod medan den testas.

I vår tidigare serie om enhetstesttekniker med Sinon.js, vi täckte hur vi kan använda Sinon.js för att stubba, spionera och håna Node.js -applikationer - särskilt HTTP -samtal.

I den här serien kommer vi att täcka enhetstesttekniker i Node.js med det finns. Jest skapades av Facebook och integreras bra med många JavaScript -bibliotek och ramverk som React, Angular och Vue för att nämna några. Det har ett särskilt fokus på enkelhet och prestanda.

I den här artikeln kommer vi att granska vad spottar är, och sedan fokusera på hur vi kan konfigurera Jest för ett Node.js -program för att håna ett HTTP -samtal i vårt test. Vi kommer sedan att jämföra hur vi använder Jest och Sinon för att skapa hån för våra program.

Vad är Mocks?

I enhetstestning ger mockor oss möjligheten att stoppa funktionaliteten som tillhandahålls av ett beroende och ett sätt att observera hur vår kod interagerar med beroendet. Mocks är särskilt användbara när det är dyrt eller opraktiskt att inkludera ett beroende direkt i våra tester, till exempel i fall där din kod ringer HTTP -anrop till ett API eller interagerar med databaslagret.

Det är att föredra att stoppa svaren för dessa beroenden, samtidigt som du ser till att de anropas efter behov. Det är här mocks kommer till nytta.

Låt oss nu se hur vi kan använda Jest för att skapa hån i Node.js.

Konfigurera Jest i ett Node.js -program

I den här självstudien kommer vi att konfigurera en Node.js -app som gör HTTP -samtal till ett JSON API som innehåller foton i ett album. Skämt kommer att användas för att håna API -anropen i våra tester.

Låt oss först skapa katalogen under vilken våra filer kommer att ligga och flytta in i den:

$ mkdir PhotoAlbumJest && cd PhotoAlbumJest

Låt oss sedan initiera Node -projektet med standardinställningarna:

$ npm init -y

När projektet har initierats fortsätter vi med att skapa ett index.js filen i katalogen:

$ touch index.js

För att hjälpa oss med HTTP -förfrågningarna använder vi Axios.

Ställa in Axios

Vi kommer att använda axios som vår HTTP -klient. Axios är en lätt, löftesbaserad HTTP-klient för Node.js som också kan användas av webbläsare. Detta gör att den passar bra för vårt användningsfall.

Låt oss först installera det:

$ npm i axios --save

Innan du använder axios, skapar vi en fil som heter axiosConfig.js genom vilket vi konfigurerar Axios -klienten. Genom att konfigurera klienten kan vi använda vanliga inställningar för en uppsättning HTTP -begäranden.

Till exempel kan vi ställa in auktoriseringsrubriker för en uppsättning HTTP -begäranden, eller oftast en bas -URL som kommer att användas för alla HTTP -förfrågningar.

Låt oss skapa konfigurationsfilen:

touch axiosConfig.js

Nu, låt oss komma åt axios och konfigurera basadressen:

const axios = require('axios'); const axiosInstance = axios.default.create({ baseURL: 'https://jsonplaceholder.typicode.com/albums'
}); module.exports = axiosInstance;

Efter inställning av baseURL, vi har exporterat axios exempel så att vi kan använda det i vår applikation. Vi kommer att använda www.jsonplaceholder.typicode.com som är ett falskt online -REST API för testning och prototyper.

I index.js fil som vi skapade tidigare, låt oss definiera en funktion som returnerar en lista med fotoadresser med ett albums ID:

const axios = require('./axiosConfig'); const getPhotosByAlbumId = async (id) => { const result = await axios.request({ method: 'get', url: `/${id}/photos?_limit=3` }); const { data } = result; return data;
}; module.exports = getPhotosByAlbumId;

För att träffa vårt API använder vi helt enkelt axios.request() vår metod axios exempel. Vi skickar in namnet på metoden, som i vårt fall är a get och url som vi kommer att åberopa.

Strängen vi skickar till url fältet sammanfogas med baseURL från axiosConfig.js.

Låt oss nu ställa in ett Jest -test för den här funktionen.

Ställer upp Jest

För att konfigurera Jest måste vi först installera Jest som ett utvecklingsberoende med npm:

$ npm i jest -D

Smakämnen -D flagga är en genväg för --save-dev, som uppmanar NPM att spara det som ett utvecklingsberoende.

Vi fortsätter sedan med att skapa en konfigurationsfil för Jest som heter jest.config.js:

touch jest.config.js

Nu, i jest.config.js fil, kommer vi att ställa in de kataloger där våra tester kommer att finnas:

module.exports = { testMatch: [ '<rootDir>/**/__tests__/**/?(*.)(spec|test).js', '<rootDir>/**/?(*.)(spec|test).js' ], testEnvironment: 'node',
};

Smakämnen testMatch value är en uppsättning globala mönster som Jest kommer att använda för att upptäcka testfilerna. I vårt fall specificerar vi att alla filer i __tests__ katalog eller någonstans i vårt projekt som har antingen en .spec.js eller.test.js tillägget bör behandlas som en testfil.

Anmärkningar: I JavaScript är det vanligt att testfiler slutar med .spec.js. Utvecklare använder "Spec" som stenografi för "Specifikation". Implikationen är att testerna innehåller funktionskraven eller specifikationerna för de funktioner som implementeras.

Smakämnen testEnvironment värde representerar miljön där Jest körs, det vill säga i Node.js eller i webbläsaren. Du kan läsa mer om andra tillåtna konfigurationsalternativ här..

Låt oss nu ändra vår package.json testskript så att det använder Jest som vår testlöpare:

"scripts": { "test": "jest"
},

Vår installation är klar. För att testa att vår konfiguration fungerar, skapa en testfil vid roten till katalogen som heter index.spec.js:

touch index.spec.js

Nu, i filen, låt oss skriva ett test:

describe('sum of 2 numbers', () => { it(' 2 + 2 equal 4', () => { expect(2 + 2).toEqual(4) });
});

Kör den här koden med följande kommando:

$ npm test

Du bör få detta resultat:

 PASS ./index.spec.js sum of 2 numbers ✓ 2 + 2 equal 4 (3ms) Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 0.897s, estimated 1s
Ran all test suites.

Med Jest korrekt konfigurerat kan vi nu fortsätta att skriva koden för att håna vårt HTTP -samtal.

Hånar ett HTTP -samtal med skämt

I index.spec.js fil, börjar vi om, tar bort den gamla koden och skriver ett nytt skript som hånar ett HTTP -samtal:

const axios = require('./axiosConfig');
const getPhotosByAlbumId = require('./index'); jest.mock('./axiosConfig', () => { return { baseURL: 'https://jsonplaceholder.typicode.com/albums', request: jest.fn().mockResolvedValue({ data: [ { albumId: 3, id: 101, title: 'incidunt alias vel enim', url: 'https://via.placeholder.com/600/e743b', thumbnailUrl: 'https://via.placeholder.com/150/e743b' }, { albumId: 3, id: 102, title: 'eaque iste corporis tempora vero distinctio consequuntur nisi nesciunt', url: 'https://via.placeholder.com/600/a393af', thumbnailUrl: 'https://via.placeholder.com/150/a393af' }, { albumId: 3, id: 103, title: 'et eius nisi in ut reprehenderit labore eum', url: 'https://via.placeholder.com/600/35cedf', thumbnailUrl: 'https://via.placeholder.com/150/35cedf' } ] }), }
}); 

Här importerar vi först våra beroenden med require syntax. Eftersom vi inte vill göra några faktiska nätverkssamtal skapar vi en manuell hån av våra axiosConfig med jest.mock() metod. De jest.mock() metod tar modulvägen som ett argument och en valfri implementering av modulen som en fabriksparameter.

För fabriksparametern anger vi att vår hån, axiosConfig, ska returnera ett objekt som består av baseURL och request(). De baseUrl är inställd på API: s basadress. De request() är en mock -funktion som returnerar en rad foton.

Smakämnen request() funktion som vi har definierat här ersätter den verkliga axios.request() fungera. När vi ringer request() metod, kommer vår hånmetod att kallas istället.

Det som är viktigt att notera är jest.fn() fungera. Det returnerar en ny hånfunktionoch dess implementering definieras inom parentes. Vad vi har gjort via mockResolvedValue() funktionen är att ge en ny implementering för request() funktion.

Vanligtvis görs detta via mockImplementation() funktion, men eftersom vi egentligen bara returnerar data som håller våra resultat - vi kan använda sockerfunktionen istället.

mockResolvedValue() är det samma som mockImplementation(() => Promise.resolve(value)).

Med en hån på plats, låt oss gå vidare och skriva ett test:

describe('test getPhotosByAlbumId', () => { afterEach(() => jest.resetAllMocks()); it('fetches photos by album id', async () => { const photos = await getPhotosByAlbumId(3); expect(axios.request).toHaveBeenCalled(); expect(axios.request).toHaveBeenCalledWith({ method: 'get', url: '/3/photos?_limit=3' }); expect(photos.length).toEqual(3); expect(photos[0].albumId).toEqual(3) });
});

Efter varje testfall ser vi till att jest.resetAllMocks() funktion kallas för att återställa tillståndet för alla spottar.

I vårt testfall kallar vi för getPhotosByAlbumId() funktion med ett ID på 3 som argument. Vi gör sedan våra påståenden.

Det första påståendet förväntar sig att axios.request() metod kallades, medan det andra påståendet kontrollerar att metoden anropades med rätt parametrar. Vi kontrollerar också att längden på den returnerade matrisen är 3 och att det första objektet i matrisen har en albumId of 3.

Låt oss köra våra nya tester med:

npm test

Vi bör få följande resultat:

PASS ./index.spec.js test getPhotosByAlbumId ✓ fetches photos by album id (7ms) Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 0.853s, estimated 1s
Ran all test suites.

Med denna nya bekantskap och erfarenhet, låt oss göra en snabb jämförelse av testupplevelserna med Jest och Sinon, som också vanligtvis används för hån.

Sinon Mocks vs Jest Mocks

Sinon.js och Jest har olika sätt att närma sig hånbegreppet. Följande är några av de viktigaste skillnaderna att notera:

  • I Jest hånas Node.js -moduler automatiskt i dina tester när du placerar mock -filerna i en __mocks__ mapp bredvid node_modules mapp. Till exempel om du en fil som heter __mock__/fs.js, sedan varje gång fs modulen kallas i ditt test, använder Jest automatiskt hånarna. Å andra sidan, med Sinon.js måste du håna varje beroende manuellt med sinon.mock() metod för varje test som behöver det.
  • I Jest använder vi jest.fn().mockImplementation() metod för att ersätta en hånad funktions implementering med ett stubbed svar. Ett bra exempel på detta finns i Jest -dokumentationen här.. I Sinon.js använder vi mock.expects() metod för att hantera det.
  • Jest tillhandahåller ett stort antal metoder för att arbeta med sitt mock API och särskilt med moduler. Du kan se dem alla här.. Sinon.js, å andra sidan, har färre metoder att arbeta med mocks och avslöjar ett generellt enklare API.
  • Sinon.js hånar fartyget som en del av Sinon.js -biblioteket som kan anslutas och användas i kombination med andra testramar som Mocha och påståendebibliotek som Chai. Jest hånar, å andra sidan, skickas som en del av Jest -ramverket, som också levereras med sina egna påståenden API.

Sinon.js -mockar är ofta mest fördelaktiga när du testar en liten applikation som kanske inte kräver hela kraften i ett ramverk som Jest. Det är också användbart när du redan har en testinställning och behöver lägga till hån mot några komponenter i din applikation.

När du arbetar med stora applikationer som har många beroenden kan det dock vara mycket fördelaktigt att utnyttja kraften i Jests mock API tillsammans med dess ram för att säkerställa en konsekvent testupplevelse.

Slutsats

I den här artikeln har vi tittat på hur vi kan använda Jest för att håna ett HTTP -samtal med axios. Vi konfigurerade först programmet för användning axios som vårt HTTP -förfrågningsbibliotek och ställ sedan in Jest för att hjälpa oss med enhetstestning. Slutligen har vi granskat några skillnader mellan Sinon.js och Jest -hån och när vi bäst skulle kunna använda det heller.

För att läsa mer om Jest mocks och hur du kan utnyttja dem för mer avancerade användningsfall, kolla in deras dokumentation här..

Som alltid kan koden från den här självstudien hittas på GitHub.

Framtiden för Java

Källa: https://stackabuse.com/using-mocks-for-testing-in-javascript-with-jes/

plats_img

VC Café

LifeSciVC

Senaste intelligens

VC Café

LifeSciVC

plats_img