mocks
Fake your API while you build the frontend or run tests.
Frontend work shouldn't have to wait for the backend. kitr/mocks answers your app's API requests with fake data, in the browser while you develop and in Node while tests run. It is Mock Service Worker with helpers for kitr's routes and errors.
Install
kitr add mocksFirst time? Run npm i -g kitr once. Inside a project, the global kitr runs your project's own version.
This installs @kitr/mocks and msw. It writes app/mocks/handlers.ts and app/mocks/browser.ts, and adds VITE_MOCKS=false to .env.
Write handlers
// app/mocks/handlers.ts
import { HttpResponse, http } from 'kitr/mocks'
export const handlers = [
http.get('*/api/me', () => HttpResponse.json({ id: 'u1', email: '[email protected]' })),
http.get('*/api/projects', () => HttpResponse.json([{ id: '1', name: 'Alpha' }])),
]
http and HttpResponse are MSW's own, so its docs apply.
In the browser
Set VITE_MOCKS=true and start the mocks before the app boots:
if (import.meta.env.DEV && import.meta.env.VITE_MOCKS === 'true') {
const { enableMocks } = await import('#app/mocks/browser')
await enableMocks()
}
Requests without a handler go to the real network, so you can fake one endpoint and keep the rest.
In tests
import { setupNodeMocks } from 'kitr/mocks'
import { afterAll } from 'vitest'
import { handlers } from '#app/mocks/handlers'
const mocks = await setupNodeMocks(handlers)
afterAll(() => mocks.close())
Use mocks.use(...) inside one test to override a handler for that test only.
Mock a whole API
With the API package, mockRoutes builds a handler for every route in your route table. You only fill in the routes you care about, by name:
import { mockRoutes } from 'kitr/mocks'
import { routes } from '#server/routes'
export const handlers = mockRoutes(routes.toJSON(), 'http://localhost:3000', {
'projects.index': () => [{ id: '1', name: 'Alpha' }],
'projects.show': ({ params }) => ({ id: params.id, name: 'Alpha' }),
})
A route with no mock answers 501 with "No mock for projects.update", so a gap is loud instead of silent. Return undefined for a 204, a Response for full control, or throw a KitrError to send an error.
Error cases
mockValidationError returns a kitr validation error, which is the easiest way to check that a form shows server errors under the right fields:
import { mockValidationError } from 'kitr/mocks'
mocks.use(mockValidationError('post', '*/api/projects', { name: ['Already taken'] }))
kitrErrorResponse(error) turns any KitrError into the same response the real server would send.