Skip to content

Testing and the mock backend

Jest + React Native Testing Library 14. render, fireEvent and userEvent are async: always await them. Prefer userEvent.setup() and getByRole / getByLabelText queries.

  • HTTP is answered by the MSW mock backend in src/mocks (the same handlers power API_MOCKS=true in dev). Override a response in one test with server.use(http.get('*/me', () => …)).
  • src/test/setup.ts mocks native modules and resets services, session, DB and query cache before each test.
  • src/test/app.ts: signInDemoUser(), in-memory SecureStore. src/test/render.tsx: renderWithProviders().
  • Coverage gate: 80% lines/functions on src/shared/ and src/data/.

API_MOCKS=true in .env.dev serves the API from src/mocks inside the app (development builds only; release bundles drop it). Demo account: demo@example.com / password123. Set API_MOCKS=false to hit API_URL.

  • In the app, src/mocks/native.ts is an axios adapter that runs the MSW handlers with getResponse(). It doesn’t patch XHR/fetch, so other traffic (images, Metro) is untouched. Unmatched requests go to the network.
  • The mock DB resets on every JS reload. Tokens are self-describing, so a signed-in session survives reloads.
  • Demo release builds (pnpm build:android:demo) bundle index.demo.js, which starts the mocks and hands the adapter to boot() via src/app/mock-backend.ts. Never import src/mocks from index.js or app code outside a __DEV__-first condition: scripts/ci/check-no-mocks-in-release.sh fails if mock code reaches a normal release bundle.
  • Add an endpoint with pnpm gen endpoint: it puts the handler in src/mocks/<feature>.ts (registered in handlers.ts), with snake_case DTOs and a test against it. Shared helpers (wait, authenticate, error) are in src/mocks/helpers.ts.