# Faker

Generate mock data factories powered by [Faker.js](https://fakerjs.dev/) from your OpenAPI specification. Faker output has no `msw` dependency, so it's useful for unit tests, Storybook stories, seed scripts, and any test setup that doesn't go through a network mock.

For Mock Service Worker request handlers, see the [MSW guide](/docs/guides/msw).

## Configuration

Add a `faker` generator entry to `output.mock.generators`:

```ts
import { defineConfig } from 'orval';

export default defineConfig({
  petstore: {
    output: {
      mode: 'single',
      target: './src/api/petstore.ts',
      schemas: './src/api/model',
      mock: {
        generators: [{ type: 'faker' }],
      },
    },
    input: {
      target: './petstore.yaml',
    },
  },
});
```

You can also combine `msw` and `faker` to emit both files in the same run:

```ts
mock: {
  generators: [{ type: 'msw' }, { type: 'faker' }],
}
```

The Faker output is written to `<filename>.faker.ts` and only depends on `@faker-js/faker`.

## Generated Output

### Response Factories

By default, Orval emits a `get<OperationId>ResponseMock` factory per operation that returns a fully-populated response value. Disable this with `operationResponses: false` (typically when combined with `schemas: true` — see below).

```ts
import { faker } from '@faker-js/faker';

export const getShowPetByIdResponseMock = (
  overrideResponse: Partial<Pet> = {},
): Pet => ({
  id: faker.number.int({ min: undefined, max: undefined }),
  name: faker.string.alpha(20),
  tag: faker.string.alpha(20),
  ...overrideResponse,
});
```

Pass overrides for any subset of fields:

```ts
const pet = getShowPetByIdResponseMock({ name: 'Buddy' });
// => { id: 7272122785202176, name: "Buddy", tag: "..." }
```

### Schema Factories

Set `schemas: true` to emit a `get<SchemaName>Mock()` factory per entry under `components/schemas`. Factories are written to a single consolidated file at `<schemas-dir>/index.faker.ts` so they can be imported uniformly and reference each other directly:

```ts
mock: {
  generators: [
    {
      type: 'faker',
      schemas: true,            // emit components/schemas factories
      operationResponses: true, // also emit per-operation response factories (default)
    },
  ],
}
```

```ts
import { faker } from '@faker-js/faker';
import type { Pet } from '.';

export const getPetMock = (overrideResponse: Partial<Pet> = {}): Pet => ({
  id: faker.number.int(),
  name: faker.string.alpha(20),
  ...overrideResponse,
});
```

When both options are enabled, the per-operation `get<Op>ResponseMock` factories **delegate** to the schema-level factories instead of re-inlining the schema body:

```ts
import { getPetMock } from './model/index.faker';

export const getShowPetByIdResponseMock = (): Pet => ({ ...getPetMock() });
```

If an operation- or tag-level `override.mock` rule targets a property of a referenced schema (by name, regex, or exact `#.path`), that single ref falls back to inlining so the override actually applies.

Requires `output.schemas` to be configured (the consolidated file is written into that directory).

### Array Item Factories

Set `arrayItems: true` on any mock generator entry to emit reusable mock factories for **object-like array item schemas** found in operation responses. This covers array elements that are inlined in the response body (not just entries under `components/schemas`). Works with both `faker` and `msw` generators:

```ts
mock: {
  generators: [
    {
      type: 'faker',
      arrayItems: true,
    },
  ],
}
```

For a paginated list response like `{ value: TenantResponseModelDto[], count: number }`, Orval emits both the operation factory and a reusable item factory:

```ts
export const getTenantResponseModelDtoMock = (
  overrideResponse: Partial<TenantResponseModelDto> = {},
): TenantResponseModelDto => ({ /* ... */, ...overrideResponse });

export const getGetTenantsByRefResponseMock = (
  overrideResponse: Partial<TenantListResponse> = {},
): TenantListResponse => ({
  value: Array.from(/* ... */).map(() => ({ ...getTenantResponseModelDtoMock() })),
  count: faker.number.int(),
  ...overrideResponse,
});
```

- **`$ref` array items** → `get<SchemaName>Mock` (shared across operations referencing the same schema) when the referenced schema is object-like.
- **Inline object array items** → `get<OperationId>Response<PropertyName>ItemMock` typed as `<ResponseName><PropertyName>Item` (matching Orval's generated item type aliases).

Orval only extracts factories for shapes it can name and mock reliably. The following fall back to inline `.map()` bodies (same as `arrayItems: false`): `$ref` to scalar schemas, `oneOf` / `anyOf` item compositions, nullable object items, and nested arrays whose parent context is not the generated response wrapper (e.g. two `items` properties under `outer` and `inner` in the same operation). Plain object items, `$ref`-to-object items, and inline `allOf` items are supported.

Top-level array responses (the array itself, not a wrapper object) reuse the same generated element alias as the schema output — a `$ref`'d array schema `CatalogItems` produces item factories typed `CatalogItemsItem`, and an inline top-level array reuses its generated `<OperationName><Status>Item` alias. Shapes where that alias cannot be derived with certainty (e.g. `$ref` array items composed via a multi-schema `allOf` with no direct properties) are inlined instead.

When `schemas: true` is also enabled, `$ref` items delegate to the consolidated schema factory instead (same as today). `arrayItems` is useful when item types only appear inside response wrappers or when you want item factories without emitting every `components/schemas` entry. With both options enabled, `$ref` items are not re-exported from the operation mock file — import `get<SchemaName>Mock` from `<schemas-dir>/index.faker.ts` instead.

## Options

Shared mock options apply to both `faker` and `msw` generator entries. Faker-only options are listed separately below.

```ts
mock: {
  generators: [
    {
      type: 'faker',
      useExamples: true,
      generateEachHttpStatus: true,
      locale: 'en_GB',
      preferredContentType: 'application/json',
      arrayItems: true,
    },
  ],
}
```

| Option | Type | Default | Description |
|---|---|---|---|
| `useExamples` | `boolean` | `false` | Seed mock values from OpenAPI `example`/`examples` fields when present. |
| `generateEachHttpStatus` | `boolean` | `false` | Emit a separate factory per HTTP status code defined in the spec (not just the success response). |
| `locale` | `keyof typeof allLocales` | — | Faker locale. Switches the import to `@faker-js/faker/locale/<x>` (e.g. `'en_GB'`, `'fr'`, `'ja'`). |
| `preferredContentType` | `string` | — | When an operation has multiple response content types, mock the one matching this MIME type. |
| `arrayItems` | `boolean` | `false` | Emit reusable mock factories for object-like array item schemas in operation responses. See [Array Item Factories](#array-item-factories). |

Faker-only options:

| Option | Type | Default | Description |
|---|---|---|---|
| `schemas` | `boolean` | `false` | Emit a consolidated `get<SchemaName>Mock` factory per `components/schemas` entry into `<schemas-dir>/index.faker.ts`. See [Schema Factories](#schema-factories). |
| `operationResponses` | `boolean` | `true` | Emit per-operation `get<OperationId>ResponseMock` factories. Set to `false` (typically with `schemas: true`) to skip operation-level factories. |

## Customizing Mock Values

Use `override.mock` to control how individual schemas, properties, and formats are mocked. These options apply to both `faker` and `msw` generators.

```ts
override: {
  mock: {
    properties: {
      // Match by property name (string or regex)
      email: () => faker.internet.email(),
      '/.*Id$/': () => faker.string.uuid(),
    },
    format: {
      // Match by OpenAPI `format` keyword
      date: () => faker.date.past().toISOString(),
      'date-time': () => faker.date.recent().toISOString(),
    },
    required: true,      // Always populate optional fields
    nonNullable: true,   // Never randomize nullable fields to null
    arrayMin: 3,
    arrayMax: 5,
    stringMin: 4,
    stringMax: 20,
    numberMin: 0,
    numberMax: 100,
    fractionDigits: 2,
  },
}
```

You can also scope overrides per-operation or per-tag via `override.operations` and `override.tags`.

### Per-schema overrides

`override.mock.properties` matches by property name, so a `color` override applies to
**every** schema that has a `color` property. To give the same property name different
mock values depending on the schema it belongs to, scope the override to a schema by name
under `override.mock.schemas`:

```ts
override: {
  mock: {
    schemas: {
      Apple: {
        properties: {
          color: () => faker.helpers.arrayElement(['red', 'green']),
        },
      },
      Car: {
        properties: {
          color: () => 'midnight black',
        },
      },
    },
  },
}
```

`getAppleMock()` now mocks `color` as a fruit color and `getCarMock()` as a car color,
even though both schemas declare `color: string`.

The keys under `properties` use the same matching rules as `override.mock.properties` —
bare property name, regex (`/.../`), or exact path (`#.foo.bar`) — but only apply to
properties of the named schema (matched against the schema's own `parentName`). When
`schemas: true` is enabled, each `get<SchemaName>Mock` factory bakes its schema-scoped
override in, so references that delegate to the factory keep the override.

**Precedence** (first match wins): `override.operations` → `override.tags` →
`override.mock.schemas` → `override.mock.properties`.

## Usage

### Unit Tests

```ts
import { describe, it, expect } from 'vitest';
import { getShowPetByIdResponseMock } from './api/petstore.faker';

describe('PetDetails', () => {
  it('renders the pet name', () => {
    const pet = getShowPetByIdResponseMock({ name: 'Buddy' });
    render(<PetDetails pet={pet} />);
    expect(screen.getByText('Buddy')).toBeInTheDocument();
  });
});
```

### Storybook

```ts
import type { Meta, StoryObj } from '@storybook/react';
import { getShowPetByIdResponseMock } from '../api/petstore.faker';
import { PetDetails } from './PetDetails';

const meta: Meta<typeof PetDetails> = {
  component: PetDetails,
};
export default meta;

export const Default: StoryObj<typeof PetDetails> = {
  args: { pet: getShowPetByIdResponseMock() },
};

export const NamedPet: StoryObj<typeof PetDetails> = {
  args: { pet: getShowPetByIdResponseMock({ name: 'Buddy' }) },
};
```

### Seed Scripts

```ts
import { writeFile } from 'node:fs/promises';
import { getListPetsResponseMock } from './api/petstore.faker';

const seed = Array.from({ length: 50 }, () => getListPetsResponseMock());
await writeFile('seed/pets.json', JSON.stringify(seed, null, 2));
```

## Deterministic Output

Faker's PRNG is seedable. Set a seed before invoking factories to get reproducible output, which is helpful for snapshot testing:

```ts
import { faker } from '@faker-js/faker';
import { getShowPetByIdResponseMock } from './api/petstore.faker';

beforeEach(() => {
  faker.seed(42);
});

it('matches snapshot', () => {
  expect(getShowPetByIdResponseMock()).toMatchSnapshot();
});
```

## Dynamic Imports

In `split` and `tags-split` modes, enable `mock.indexMockFiles` to emit an `index.faker.ts` barrel — aggregating the per-tag faker files in `tags-split`, or re-exporting the single faker file in `split`:

```ts
export default defineConfig({
  petstore: {
    output: {
      mode: 'tags-split',
      mock: {
        indexMockFiles: true,
        generators: [{ type: 'faker' }],
      },
    },
  },
});
```
