Quando usamos React Query em nossos projetos, temos uma série de funcionalidades poderosas ao nosso dispor: cache, refetch automåtico, invalidaçÔes, estados de carregamento e erro, etc. Mas tudo isso pode ser facilmente comprometido se mockarmos diretamente o useQuery nos testes.
Neste artigo, vamos ver como usar o MSW (Mock Service Worker) para simular endpoints reais nos testes, preservando toda a inteligĂȘncia do React Query â e evitando mocks frĂĄgeis e irreais.
đ« O que NĂO fazer: mockar o useQuery diretamente
jest.mock('@tanstack/react-query', () => ({
useQuery: () => ({ data: [{ id: 1, name: 'Test' }], isLoading: false }),
}));
Esse tipo de mock âquebraâ toda a mĂĄgica do React Query:
- â NĂŁo testa cache, nem invalidation
- â NĂŁo simula estados reais como loading/error
- â Cria um acoplamento forte e frĂĄgil entre seu componente e o teste
â
O que fazer: usar MSW para simular o endpoint real
Com MSW, vocĂȘ intercepta requisiçÔes reais (fetch/axios) e devolve respostas mockadas â sem perder a lĂłgica de cache, revalidação e fallback do React Query.
đŠ Setup do MSW no projeto
1. Instale a lib
npm install msw --save-dev
2. Crie seus handlers
// src/mocks/handlers.ts
import { rest } from 'msw';
export const handlers = [
rest.get('/api/users', (req, res, ctx) => {
return res(
ctx.status(200),
ctx.json([{ id: 1, name: 'Rayza' }, { id: 2, name: 'Vitor' }])
);
}),
];
3. Configure o servidor para testes
// src/mocks/server.ts
import { setupServer } from 'msw/node';
import { handlers } from './handlers';
export const server = setupServer(...handlers);
4. Integre com Jest
// src/setupTests.ts
import '@testing-library/jest-dom';
import { server } from './mocks/server';
beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
E adicione no jest.config.ts:
setupFilesAfterEnv: ['/src/setupTests.ts '],
đ§Ș Exemplo prĂĄtico: testando listagem de usuĂĄrios
Componente
// UserList.tsx
import { useQuery } from '@tanstack/react-query';
import axios from 'axios';
export function UserList() {
const { data, isLoading, error } = useQuery(['users'], async () => {
const res = await axios.get('/api/users');
return res.data;
});
if (isLoading) return <p>Loading...p>;
if (error) return <p>Error!p>;
return (
<ul>
{data.map((user: any) => (
<li key={user.id}>{user.name}li>
))}
ul>
);
}
Teste com MSW
// UserList.test.tsx
import { render, screen, waitFor } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { UserList } from './UserList';
const queryClient = new QueryClient();
function renderWithClient(ui: React.ReactElement) {
return render(
<QueryClientProvider client={queryClient}>{ui}QueryClientProvider>
);
}
test('renders user list from mocked endpoint', async () => {
renderWithClient(<UserList />);
expect(screen.getByText(/loading/i)).toBeInTheDocument();
await waitFor(() => {
expect(screen.getByText('Rayza')).toBeInTheDocument();
expect(screen.getByText('Vitor')).toBeInTheDocument();
});
});
â
Por que usar MSW?
Vantagens prĂĄticas:
- â VocĂȘ testa a integração real com a API (mesmo que fake)
- â O React Query funciona de verdade: cache, refetch, status
- â
VocĂȘ cobre casos de sucesso, erro, loading e atĂ© delay com
ctx.delay() - â Mocks mais fĂĄceis de manter e reutilizar em testes E2E (Playwright/Cypress)
âš ConclusĂŁo
Evitar mocks diretos de useQuery Ă© uma boa prĂĄtica quando usamos React Query. Com o MSW, conseguimos simular uma API realista e manter todo o comportamento que faz do React Query uma ferramenta tĂŁo poderosa.
Mockar o endpoint, nĂŁo o hook. Isso garante testes mais prĂłximos da realidade, mais confiĂĄveis e fĂĄceis de evoluir.
