Standards Docs
Guides

Testing

Test Standards React and runtime code with public mock helpers.

Standards exposes public testing helpers for the two places most application tests need a controlled environment: React components/hooks and runtime services. Prefer these helpers over hand-built mocks so your tests keep the same provider, query-key, and service behavior as production code.

React tests

Use MockSchemaProvider when a component or hook expects SchemaClientProvider, React Query, translations, relation batching, or create-modal context. Seed only the objects, records, forms, views, users, permissions, or relation options the test reads.

// @noverify
import {
  MockSchemaProvider,
  createMockObject,
  createMockRecord,
} from "@stndrds/react/testing";

export function renderWithStandards(ui: React.ReactNode) {
  return (
    <MockSchemaProvider
      data={{
        objects: [createMockObject({ name: "contacts", label: "Contact" })],
        records: {
          contacts: [
            createMockRecord({
              id: "contact-1",
              label: "Ada Lovelace",
              values: { firstName: "Ada", lastName: "Lovelace" },
            }),
          ],
        },
      }}
    >
      {ui}
    </MockSchemaProvider>
  );
}

Use mock handlers when the behavior under test is an interaction instead of static seeded data. For example, pass handlers.onCreateRecord to assert the values a create flow sends, or handlers.onLoadRelationOptions to return different relation options for a specific search input.

Do not mock Standards hooks by duplicating their query keys or cache update logic. Component and hook tests should render through MockSchemaProvider so recordsKeys, invalidation, optimistic state, and context wiring stay owned by the React package.

Runtime tests

Use runtime test services when you want to exercise real service logic with a test adapter. They are useful for module tests that need record validation, relations, computed invalidation, search indexing, or schema service behavior without booting the full application container.

// @noverify
import { createMockAdapter } from "@stndrds/runtime";
import { createTestRecordService, createTestSearchAdapter } from "@stndrds/runtime/testing";

const adapter = createMockAdapter();
const search = createTestSearchAdapter();
adapter.search = search;

const records = createTestRecordService(adapter);

createTestSearchAdapter returns a Vitest-friendly search adapter whose methods are vi.fn() calls with safe default responses. Override only the methods a test needs to observe. Attach it to the same DatabaseAdapter you pass to the runtime service factory so record writes, schema updates, and search assertions exercise one coherent test boundary.

createTestRecordService(adapter) mirrors the runtime container wiring around records, relations, schema lookup, reference edges, computed invalidation, and optional background jobs. Use it when the behavior under test depends on runtime service coordination rather than a single pure function.

Keep runtime mocks at the adapter boundary. Avoid reimplementing RecordService or query-builder behavior in tests; that usually proves the mock instead of the runtime contract.

Docs snippet validation

Non-generated guide examples are checked by the docs package. Run the snippet validator before editing guides with TypeScript or TSX fences:

pnpm --filter @stndrds/docs validate:examples
pnpm --filter @stndrds/docs check

Leave snippets verifiable when they are self-contained TypeScript or TSX. Add // @noverify as the first line inside a code fence only when the example depends on app-local imports, generated schema packages, framework globals, or runtime objects such as recordService that are explained in prose.

On this page