R
Interview Deckreact · next.js · senior/staff
0·0·122
Testing

Mocking com MSW (Mock Service Worker)

Interceptar requests no nível da rede com MSW. Sem axios-mock, sem jest.mock de fetch.

MSW (Mock Service Worker) intercepta requisições HTTP no nível de rede usando Service Worker (browser) ou interceptors Node.js (para Jest/Vitest). Vantagem sobre jest.mock(fetch): o componente usa exatamente o mesmo código de produção, só a rede é mockada. Funciona com qualquer lib HTTP (fetch, axios, ky) sem mudar o código de produção.

Problema
jest.mock('../api/users') acopla os testes à implementação da camada de API. Se você trocar fetch por axios, todos os mocks quebram. E você não testa o código HTTP real.
Solução
MSW define handlers por URL/método. Em testes, usa setupServer() do msw/node. O componente faz fetch normalmente, o MSW intercepta antes de chegar à rede e retorna o mock. Mesmo handler pode ser usado em Storybook e no browser de dev.
Tip
MSW é a forma moderna de mock de API. Um handler.ts compartilhado entre testes, Storybook e dev server elimina duplicação de mocks. Defina cenários de erro explicitamente: server.use(http.get('/api/users', () => HttpResponse.error())).
// handlers.ts — compartilhado entre testes, Storybook, dev
import { http, HttpResponse } from 'msw'

export const handlers = [
  http.get('/api/users', () => {
    return HttpResponse.json([
      { id: 1, name: 'Alice' },
      { id: 2, name: 'Bob' },
    ])
  }),

  http.post('/api/users', async ({ request }) => {
    const body = await request.json()
    return HttpResponse.json({ id: 3, ...body }, { status: 201 })
  }),
]

// setup nos testes (Jest/Vitest)
import { setupServer } from 'msw/node'
const server = setupServer(...handlers)

beforeAll(() => server.listen())
afterEach(() => server.resetHandlers())
afterAll(() => server.close())

// Sobrescrever para cenário de erro em teste específico
test('mostra erro quando API falha', async () => {
  server.use(
    http.get('/api/users', () => new HttpResponse(null, { status: 500 }))
  )
  render(<UserList />)
  expect(await screen.findByText(/erro ao carregar/i)).toBeInTheDocument()
})
Q.MSW vs jest.mock vs axios-mock-adapter?
A.MSW intercepta na camada de rede — o mais realista. jest.mock mocka módulos inteiros (acopla à implementação). axios-mock-adapter só funciona com Axios. MSW funciona independente de qual lib HTTP o componente usa e não requer mudança no código de produção.
Q.Como testar estados de erro com MSW?
A.server.use() para sobrescrever um handler em um teste específico: server.use(http.get('/api/users', () => new HttpResponse(null, { status: 500 }))). Depois do teste, o handler original volta (server.resetHandlers() no afterEach).
Q.MSW funciona com React Query?
A.Sim — e é a combinação ideal. O componente usa useQuery normalmente, o MSW intercepta o fetch do React Query, e você testa o componente completo incluindo loading/error/success states sem mock nenhum no código de produção.
73/122← →