Testing / Mocking

    MSW i API Mocking w React

    MSW 2.0 (http/HttpResponse, Browser+Node), Vitest+RTL integration, Storybook mocking i contract testing z Pact.

    MSW 2.0
    Network-level
    Storybook
    Story mocking
    Pact
    Contract tests
    Vitest+RTL
    Node testing

    6 narzędzi API mocking — porównanie

    MSW, nock, fetch-mock, axios-mock-adapter, Pact i WireMock — środowisko, API, integracja i kiedy użyć.

    Narzędzie Środowisko API Integracja Kiedy
    MSW 2.0 Browser + Node http, HttpResponse (native fetch) RTL, Vitest, Storybook, Playwright Standard — najlepszy wybór 2024
    nock Node.js only nock(url).get(path).reply() Jest, Mocha, Vitest Node.js only, legacy projects
    fetch-mock Browser + Node fetchMock.get(url, response) Jest, Vitest Prosty fetch mocking, minimalna setup
    axios-mock-adapter Browser + Node mock.onGet('/url').reply() Dowolne Projekty z Axios, stary pattern
    Pact Browser + Node PactV3 consumer/provider Pact Broker, CI/CD Contract testing microservices
    WireMock Serwer (Java) JSON stub mappings Dowolne (HTTP) Enterprise, Java teams, shared stubs

    Często zadawane pytania

    Co to jest MSW (Mock Service Worker) i jak działa?

    MSW (Mock Service Worker): biblioteka do mockowania HTTP requestów. Działa na poziomie sieciowym (nie patch fetch). Browser: Service Worker przechwytuje requesty. Node.js: interceptor requestów. Instalacja: npm install msw --save-dev. npx msw init public/ --save (dla przeglądarki). Wersja 2.0 (2023): nowe API. http.get zamiast rest.get. HttpResponse.json() zamiast res(ctx.json()). Native Fetch API. Handlers: import {http, HttpResponse} from 'msw'. const handlers = [http.get('/api/users', () => {return HttpResponse.json([{id: 1, name: 'Adam'}])}), http.post('/api/users', async ({request}) => {const body = await request.json(); return HttpResponse.json({...body, id: 2}, {status: 201})})]. Browser setup: import {setupWorker} from 'msw/browser'. const worker = setupWorker(...handlers). worker.start(). Node.js setup (testy): import {setupServer} from 'msw/node'. const server = setupServer(...handlers). beforeAll(() => server.listen()). afterEach(() => server.resetHandlers()). afterAll(() => server.close()). Dlaczego MSW: interceptuje na poziomie sieci (jak realne requesty). Działa w Browser + Node. Jeden zestaw handlerów dla testów + development. Nie wymaga zmiany kodu aplikacji. Obsługuje REST i GraphQL. TypeScript support natywny. Alternatywy: nock (Node only). axios-mock-adapter. fetch-mock. Jest spyOn(global, 'fetch'). MSW jest bardziej realistyczny.

    MSW 2.0 — co zmieniło się w API i jak migrować?

    MSW 1.x (stare API): import {rest} from 'msw'. rest.get('/users', (req, res, ctx) => {return res(ctx.json([...]), ctx.status(200))}). Problemy: ctx API — nieintuicyjne. Nie-native fetch. Trudne do typowania requestów. MSW 2.0 (nowe API): import {http, HttpResponse, graphql} from 'msw'. http.get('/users', () => {return HttpResponse.json([...])}). http.post('/users', async ({request}) => {const body = await request.json()}). Kluczowe zmiany v2: rest -> http. ctx.json() -> HttpResponse.json(). ctx.status() -> drugi argument HttpResponse. ctx.delay() -> usunięte, użyj delay() import. resolver params: ({request, params, cookies}). request: natywny Request. params: path parameters. cookies: cookies. Typy TypeScript: http.get('/users/:id', ({params}) => {const {id} = params}). HTTP Response z delay: import {delay} from 'msw'. await delay(500). Passthrough (nie mockuj): import {passthrough} from 'msw'. return passthrough(). Error handling: HttpResponse.json({error: 'Not found'}, {status: 404}). GraphQL mocking: graphql.query('GetUser', ({variables}) => {return HttpResponse.json({data: {user: {id: variables.id}}})}). graphql.mutation('CreateUser', ...). Migracja v1->v2: automatyczny codemod (msw-codemods). Większość zmian mechanicznych. Sprawdź custom resolvers.

    Testing z MSW + React Testing Library + Vitest?

    Setup (Vitest + RTL + MSW): npm install msw @testing-library/react @testing-library/jest-dom vitest --save-dev. vitest.config.ts: environment: 'jsdom'. setupFiles: ['./src/test/setup.ts']. setup.ts: import '@testing-library/jest-dom'. import {server} from './mocks/server'. beforeAll(() => server.listen({onUnhandledRequest: 'error'})). afterEach(() => server.resetHandlers()). afterAll(() => server.close()). handlers.ts: export const handlers = [http.get('/api/todos', () => {return HttpResponse.json([{id: 1, title: 'Buy milk', done: false}])})]. server.ts: import {setupServer} from 'msw/node'. export const server = setupServer(...handlers). Test komponentu: it('displays todos from API', async () => {render(TodoList). await waitFor(() => screen.getByText('Buy milk')). expect(screen.getByText('Buy milk')).toBeInTheDocument()}). Override handler w teście: server.use(http.get('/api/todos', () => {return HttpResponse.json([], {status: 500})})). Testuj error state. Testuj loading state: render(TodoList). expect(screen.getByText('Loading...')).toBeInTheDocument(). await waitFor(() => screen.getByText('Buy milk')). React Query + MSW: QueryClientProvider w teście. QueryClient z retry: 0 (szybkie testy). MSW zwraca dane -> React Query cachuje -> komponent renderuje. Async tests: await screen.findByText('text') zamiast waitFor. findBy* zawiera wbudowany waitFor.

    MSW w Storybook — development mocking?

    MSW + Storybook: msw-storybook-addon. Mockuj API w Storiesach. Każda story może mieć własne handlery. Instalacja: npm install msw-storybook-addon --save-dev. .storybook/preview.ts: import {initialize, mswLoader} from 'msw-storybook-addon'. initialize(). export const loaders = [mswLoader]. Story z MSW: import {http, HttpResponse} from 'msw'. export const Success: Story = {parameters: {msw: {handlers: [http.get('/api/user', () => {return HttpResponse.json({name: 'Adam', role: 'admin'})})]}}. export const Error: Story = {parameters: {msw: {handlers: [http.get('/api/user', () => {return HttpResponse.json({error: 'Unauthorized'}, {status: 401})})]}}. Korzyści: visual testing różnych stanów API. Dokumentacja interaktywna z realnymi danymi. Brak potrzeby backendu do development. Chromatic: visual regression testing. Screenshot stories z różnymi API stanami. CI pipeline testing. Storybook 8 nowości: Storybook 8 (2024). Vitest integration (--vitest mode). Chromatic TurboSnap. Szybsze builds. React Server Components support. MSW w development (browser): index.tsx/main.tsx: if (process.env.NODE_ENV === 'development') {const {worker} = await import('./mocks/browser'); await worker.start({onUnhandledRequest: 'bypass'})}. Zakomentowane API calls w .env.local? Lepiej: MSW conditional start. Debugowanie: MSW DevTools (unofficial). Network tab w DevTools — requesty widoczne jako przez SW. console.log w handlerach. Dodaj 'MSW: ' prefix do logów.

    Contract Testing z Pact — zaawansowane API mocking?

    Contract Testing: consumer definiuje kontrakt co oczekuje od API. Provider weryfikuje czy spełnia kontrakt. Automatyczna weryfikacja kompatybilności. Pact: najpopularniejsza biblioteka contract testing. @pact-foundation/pact. Consumer-driven contracts. Pact Broker — serwer do przechowywania kontraktów. Consumer test (React app -> API): import {PactV3, MatchersV3} from '@pact-foundation/pact'. const {string, integer} = MatchersV3. Pact opisuje: oczekiwany request. Oczekiwana response. Pact generuje kontrakt JSON. Provider verification (backend Node.js): @pact-foundation/pact (provider side). Wczytaj kontrakt z Pact Broker. Uruchom testy przeciwko realnemu serwerowi. Kiedy Pact: microservices. Niezależne deploymenty. Różne teams. CI/CD. Pact vs MSW: MSW — mocking w unit/integration tests. Pact — contract testing między services. Komplementarne, nie konkurencyjne. Consumer-Driven Contract (CDC): consumer prowadzi zmiany API. Provider musi spełnić kontrakt. Bezpieczeństwo przed breaking changes. Pact Broker: publiczny SaaS lub self-hosted. Przechowuje kontrakty między wersje. Can-I-Deploy: weryfikuj przed deployment. Matryce kompatybilności. WireMock: Java-based API mocking. Stub mappings w JSON. Dobry dla Java + TS teams. Karate DSL: BDD + API testing + mocking. Scenariusze w Gherkin. Szczególnie dla QA teams.

    Czytaj dalej

    Powiązane artykuły

    Kontakt

    Skontaktuj się z nami

    Porozmawiajmy o Twoim projekcie. Bezpłatna wycena w ciągu 24 godzin.

    Wyślij zapytanie

    Bezpłatna wycena w 24h
    Bez zobowiązań
    Indywidualne podejście
    Ekspresowa realizacja

    Telefon

    +48 790 814 814

    Pon-Pt: 9:00 - 18:00

    Email

    adam@fotz.pl

    Odpowiadamy w ciągu 24h

    Adres

    Plac Wolności 16

    61-739 Poznań

    Godziny pracy

    Pon - Pt9:00 - 18:00
    Sob - NdzZamknięte

    Wolisz porozmawiać?

    Zadzwoń teraz i porozmawiaj z naszym specjalistą o Twoim projekcie.

    Zadzwoń teraz