O Jest roda no Node - não há câmera, GPS ou Keychain. O jest-expo substitui a maioria dos módulos do Expo SDK com padrões seguros; você adiciona mocks manuais quando seus testes precisam de resultados específicos de permissão, leituras de sensor ou comportamento de SDK nativo de terceiros.
Preset jest-expo instala mocks padrão para módulos Expo para que as importações não travem o Jest. Os padrões retornam promessas resolvidas com formas genéricas de "sucesso" - raramente correspondendo aos seus casos de borda de produção.
jest.mock("module-name") é içado para o topo do arquivo e troca o módulo antes que suas importações sejam avaliadas. Funciona para expo-*, @react-native-async-storage/async-storage e módulos locais do app.
Mocks manuais em __mocks__/ ao lado do nome do pacote node_modules ou arquivo src/ se aplicam quando você chama jest.mock sem um factory.
Padrão de spy - jest.spyOn(module, "fn") envolve uma única função, deixando o resto real (quando não totalmente mockado).
Mock de fronteira - mock src/services/api.ts, não fetch e não cada importação transitiva, a menos que esteja testando o próprio cliente HTTP.
Sistema operacional abrindo o app a partir do estado frio
Trate mocks nativos do Jest como testes de contrato para sua reação em JS - não prova que a ponte nativa funciona. Adicione Maestro E2E ou QA manual para caixas de diálogo de permissão e caminhos de hardware.
Assumir que os padrões do jest-expo correspondem ao seu teste - Mocks de permissão padrão frequentemente retornam granted. Testes nunca exercitam caminhos de negação a menos que você substitua. Correção: Defina mockResolvedValue para cada cenário de permissão/status explicitamente.
Mockar muito profundamente - Mockar internos do react-native ou cada importação expo-* torna os testes frágeis quando atualizações do SDK mudam assinaturas. Correção: Mocke a fronteira do seu serviço; mantenha um módulo responsável pelas chamadas nativas.
Esquecer jest.clearAllMocks() - Contagens de chamadas e implementações enfileiradas vazam entre testes. Correção:afterEach em jest.setup.ts ou beforeEach em blocos describe que usam spies.
jest.requireActual após mock completo - Espalhar requireActual para módulos nativos pode puxar bindings nativos reais para o Jest e travar. Correção: Mocke apenas as funções que você chama; evite requireActual em módulos que tocam código nativo.
Falsas confianças de suítes verdes - Todo o comportamento nativo é simulado; a produção ainda falha em um dispositivo real. Correção: Documente quais fluxos precisam de Maestro ou verificações manuais em dispositivo em modelos de PR.
import() dinâmico contornando mocks - Importações preguiçosas podem resolver antes que jest.mock se aplique se mal ordenadas. Correção: Use importações estáticas no código sob teste, ou jest.unstable_mockModule para caminhos de importação dinâmica ESM.
Duplicar configuração de mock em cada arquivo - Mocks de expo-font copiados e colados desviam. Correção: Utilitários compartilhados em test-utils/native-mocks.ts ou mocks globais em jest.setup.ts para módulos de todo o app (fontes, tela de splash).
Ele mocka a maioria dos pacotes expo-* enviados com o SDK. Módulos nativos customizados, SDKs de terceiros bare e alguns pacotes da comunidade não são cobertos - adicione jest.mock manualmente.
Onde coloco mocks compartilhados?
Para todo o app: jest.setup.ts (fontes, tela de splash, constantes).
Específico da funcionalidade: topo do arquivo de teste ou __tests__/helpers/.
Estilo de pacote: __mocks__/expo-location.ts na raiz do projeto para que jest.mock("expo-location") resolva automaticamente.
jest.mock vs jest.spyOn?
jest.mock substitui o módulo inteiro - use para pontes nativas.
jest.spyOn envolve um método - use quando a maior parte do módulo deve permanecer real (raro com módulos nativos no Jest).
O pacote envia um mock oficial do Jest - prefira-o a objetos chave-valor feitos à mão.
Como mocko o expo-router?
Prefira renderRouter de expo-router/testing-library em vez de mockar useRouter ao testar navegação. Para componentes folha, passe callbacks de navegação como props em vez de mockar o hook do router.
Use com moderação - requireActual em módulos com muita carga nativa pode falhar; um módulo wrapper fino é mais seguro.
Por que meu mock não se aplica?
jest.mock deve estar no escopo do módulo (içado), não dentro de it/beforeEach.
Certifique-se de que o caminho de importação corresponda exatamente ao que o código de produção importa.
Limpe o cache do Metro/Jest: npx jest --clearCache.
Devo mockar fetch ou o cliente da API?
Mocke src/api/client ou o wrapper queryFn do TanStack Query - não ambos. Uma fronteira mantém os testes focados em como o app lida com respostas de sucesso e erro.
Corresponda à forma dos tipos TypeScript do módulo Expo real - objetos incompletos causam falsos positivos.
O que é falsa confiança?
Testes passam porque mocks sempre retornam sucesso, enquanto usuários reais encontram caixas de diálogo de negação, modo avião ou bugs do SO. Complemente o Jest com Maestro E2E para caminhos de integração de permissão e SO.
Como testo um módulo nativo Expo customizado?
Crie uma fachada TypeScript que importe seu módulo. No Jest, jest.mock("@/modules/my-native-module") com um mock manual retornando a API JS que seu app espera. Valide o módulo real em builds de dispositivo.
Mocks pertencem a setupFilesAfterEnv?
Apenas para módulos que todo teste precisa (fontes, tela de splash, silêncio do reanimated). Mocks de funcionalidades pertencem perto dos testes que os afirmam - mocks globais escondem a configuração ausente em novos testes.
Como reseto mocks entre testes?
afterEach(() => { jest.clearAllMocks(); // clears call history // jest.resetAllMocks(); // also resets implementations - use when tests override mockResolvedValue});
Adicione a jest.setup.ts para consistência em todo o projeto.