Node.js dla początkujących - Część 16: Testy jednostkowe - Jest
Mateusz Kędziora

Hej! Witaj w kolejnym artykule z naszego kursu JavaScript dla początkujących. Dziś zanurzymy się w temat testowania Twojego kodu, a konkretnie – testowania aplikacji Node.js za pomocą popularnego frameworka Jest. Zastanawiasz się pewnie, po co w ogóle testować kod? Wyobraź sobie, że budujesz skomplikowany program, który ma wiele funkcji. Zmiana jednej linijki kodu może nieoczekiwanie zepsuć coś w zupełnie innym miejscu. Testy pozwalają nam tego uniknąć, dając pewność, że nasz kod działa zgodnie z oczekiwaniami.
Dlaczego Jest?
Jest to wszechstronny framework testowy, który oferuje wszystko, czego potrzebujemy do testowania kodu JavaScript, zarówno po stronie klienta (w przeglądarce), jak i po stronie serwera (Node.js). Jest szybki, łatwy w konfiguracji i oferuje wiele przydatnych funkcji, takich jak:
- Szybkie uruchamianie testów: Jest uruchamia testy równolegle, co znacznie skraca czas oczekiwania na wyniki.
- Wbudowane mockowanie: Umożliwia łatwe izolowanie testowanego kodu od zależności zewnętrznych.
- Łatwa konfiguracja: Nie wymaga skomplikowanej konfiguracji, co pozwala szybko rozpocząć pisanie testów.
- Doskonała dokumentacja: Posiada rozbudowaną i czytelną dokumentację.
Wprowadzenie
Instalacja Jest
Zacznijmy od instalacji. Jeśli masz już zainstalowany Node.js i npm (Node Package Manager), otwórz terminal i w katalogu projektu wykonaj polecenie:
npm install --save-dev jest
Flaga --save-dev
oznacza, że Jest zostanie zainstalowany jako zależność deweloperska (nie będzie potrzebny w finalnej wersji aplikacji).
Pierwszy test jednostkowy
Stwórzmy prosty moduł, który będzie zawierał funkcję dodającą dwie liczby:
// math.js
function add(a, b) {
return a + b;
}
module.exports = add;
Teraz stwórzmy plik testowy o nazwie math.test.js
(konwencja nazewnicza: nazwa_pliku.test.js
lub nazwa_pliku.spec.js
):
// math.test.js
const add = require('./math');
test('dodawanie 2 i 3 powinno dać 5', () => {
expect(add(2, 3)).toBe(5);
});
Omówienie testu
const add = require('./math');
– importujemy funkcjęadd
z naszego modułu.test('opis testu', () => { ... });
– definiujemy test. Opis testu powinien być krótki i zwięzły, a jednocześnie precyzyjnie opisywać, co jest testowane.expect(add(2, 3)).toBe(5);
– to tzw. asercja. Sprawdzamy, czy wynik wywołania funkcjiadd(2, 3)
jest równy 5.toBe()
to jeden z wielu dostępnych matcherów (funkcji porównujących).
Uruchamianie testów
Aby uruchomić testy, dodaj do pliku package.json
w sekcji scripts
następujący wpis:
"scripts": {
"test": "jest"
}
Teraz w terminalu możesz wykonać polecenie:
npm test
Powinieneś zobaczyć wynik testu, informujący o tym, czy test zakończył się sukcesem (PASS) czy porażką (FAIL).
Inne matchery
Oprócz toBe()
Jest oferuje wiele innych matcherów, np.:
toBeGreaterThan(number)
: Sprawdza, czy wartość jest większa od podanej liczby.toBeLessThan(number)
: Sprawdza, czy wartość jest mniejsza od podanej liczby.toEqual(value)
: Sprawdza, czy wartość jest równa podanej wartości (działa również dla obiektów i tablic).toContain(item)
: Sprawdza, czy tablica zawiera dany element.toThrow(error)
: Sprawdza, czy funkcja rzuca wyjątek.
Przykład z użyciem toEqual()
:
test('obiekty są równe', () => {
const data = { one: 1 };
data['two'] = 2;
expect(data).toEqual({ one: 1, two: 2 });
});
Testowanie funkcji asynchronicznych
Do testowania funkcji asynchronicznych możemy użyć async/await
lub promises
.
Przykład z async/await
:
async function fetchData() {
return new Promise(resolve => {
setTimeout(() => {
resolve('dane');
}, 100);
});
}
test('pobieranie danych asynchronicznie', async () => {
const data = await fetchData();
expect(data).toBe('dane');
});
Mockowanie
Mockowanie pozwala nam izolować testowany kod od zależności zewnętrznych, takich jak bazy danych, API czy inne moduły. Jest oferuje wbudowane mechanizmy mockowania.
Przykład mockowania modułu:
// api.js
function getDataFromApi() {
// Symulacja pobierania danych z API
return new Promise(resolve => {
setTimeout(() => {
resolve({ message: 'Dane z API' });
}, 100);
});
}
module.exports = { getDataFromApi };
// api.test.js
const { getDataFromApi } = require('./api');
jest.mock('./api', () => ({
getDataFromApi: jest.fn(() => Promise.resolve({ message: 'Mockowane dane' })),
}));
test('test z mockowaniem API', async () => {
const data = await getDataFromApi();
expect(data.message).toBe('Mockowane dane');
expect(getDataFromApi).toHaveBeenCalled(); // Sprawdzamy, czy funkcja mock została wywołana
});
W tym przykładzie zamockowaliśmy funkcję getDataFromApi
, zwracając zamiast rzeczywistych danych, mockowane dane. Dzięki temu test jest niezależny od stanu API.
Grupy testów (describe
)
Możemy grupować testy za pomocą funkcji describe
. To pomaga w organizacji testów i poprawia ich czytelność.
describe('Testy funkcji dodawania', () => {
test('dodawanie 2 i 3 powinno dać 5', () => {
expect(add(2, 3)).toBe(5);
});
test('dodawanie -1 i 1 powinno dać 0', () => {
expect(add(-1, 1)).toBe(0);
});
});
Praca domowa
- Stwórz moduł, który będzie zawierał funkcję obliczającą pole prostokąta.
- Napisz testy jednostkowe dla tej funkcji, używając różnych matcherów (np.
toBe()
,toBeGreaterThan()
). - Stwórz moduł, który będzie pobierał dane z fikcyjnego API (możesz użyć
setTimeout
do symulacji opóźnienia). - Napisz testy, mockując funkcję pobierającą dane z API.
- Pogrupuj testy za pomocą
describe
.
Podsumowanie
Testowanie to kluczowy element procesu tworzenia oprogramowania. Dzięki Jest możemy pisać testy jednostkowe w sposób prosty i efektywny, zapewniając wysoką jakość naszego kodu. Zachęcam Cię do dalszego eksperymentowania z Jest i odkrywania jego możliwości. Pamiętaj, że praktyka czyni mistrza!
Dodatkowe wskazówki
- Staraj się pisać testy przed napisaniem kodu (TDD – Test-Driven Development).
- Pisz testy dla każdego przypadku użycia, w tym dla przypadków brzegowych i błędnych danych wejściowych.
- Dbaj o to, aby testy były krótkie, zwięzłe i czytelne.
- Regularnie uruchamiaj testy, aby szybko wykrywać błędy.
Mam nadzieję, że ten artykuł był dla Ciebie pomocny. Jeśli masz jakieś pytania, śmiało zadawaj
Polecane artykuły
Docker vs Kubernetes: Który dla Ciebie w 2025?
Docker i Kubernetes objaśnione! Która technologia lepsza dla początkujących w 2025? Porównanie, przykłady i przyszłość.
Mateusz Kędziora
DevOps: Automatyzacja zadań sysadmina dla programistów
Zautomatyzuj pracę sysadmina w środowisku DevOps! Praktyczne przykłady, skrypty, Ansible, Terraform, Prometheus i Grafana.
Mateusz Kędziora
Automatyzacja Linux/macOS z Bash: Praktyczny Przewodnik
Zacznij automatyzować system Linux/macOS z Bash! Dowiedz się, czym jest Bash, jak pisać skrypty i używać podstawowych komend.
Mateusz Kędziora