UNPKG

openapi-mock-gen

Version:

Generate mock definitions with random fake data based on OpenAPI spec.

288 lines (204 loc) 9.76 kB
# `openapi-mock-gen` Effortlessly auto-generate mock data based on your OpenAPI specification. Inspired by `msw-auto-mock`, this CLI tool is designed to be powerful, flexible, and tool-agnostic. ## Why `openapi-mock-gen`? - **Zero-Effort Mocks**: Go from an OpenAPI spec to fully-generated mock data in seconds. - **Highly Customizable**: Fine-tune data generation globally or per-endpoint with a simple config file. - **Realistic Data**: Leverages `@faker-js/faker` to produce realistic and dynamic data for your mocks. - **Tool-Agnostic**: By default, it only generates the mock data and a manifest file. You can use it with any tool you want. - **TypeScript-Ready**: Comes with first class support for TypeScript with the help of [`openapi-typescript`](https://www.npmjs.com/package/openapi-typescript). - **Schema Validation**: We help detect the type mismatch between the schema and the provided example and warn you about it to catch the issue early. (Only if `useExample` is set to `true`). ## Installation Installation is optional. You can execute it directly with `npx` or: ```bash npm install openapi-mock-gen --save-dev ``` ## Quick Start 1. **Initialize**: Generate a configuration file (`mock.config.js`) in your project root by running the following command: ```bash npx openapi-mock-gen@latest init #if you have installed it as a dev dependency openapi-mock-gen init ``` 2. **Configure**: Edit `mock.config.js` to point to your OpenAPI specification. ```javascript // mock.config.mjs export default { specPath: 'https://petstore.swagger.io/v2/swagger.json', outputDir: '.mocks', // ... and more options }; ``` 3. **Generate**: Run the generator to create your mock files. ```bash npx openapi-mock-gen@latest #if you have installed it as a dev dependency openapi-mock-gen ``` This will generate mock data files and a `manifest.json` in your specified `outputDir`. ## CLI Options ### `init` Initialize the `mock.config.js` file in your project root. ```bash npx openapi-mock-gen@latest init [options] #if you have installed it as a dev dependency openapi-mock-gen init [options] ``` **Options:** | Option | Description | | ----------------------------- | ------------------------------------ | | `-p, --specPath <specPath>` | Path to the OpenAPI spec file. | | `-o, --outputDir <directory>` | Output directory for the mock files. | | `-b, --baseUrl <baseUrl>` | Base URL for the mock server. | | `-t, --typescript` | Generate TypeScript types. | ### `generate` (default) Generate mock data and the manifest file based on your config. ```bash npx openapi-mock-gen@latest [adapter] #if you have installed it as a dev dependency openapi-mock-gen [adapter] [options] ``` **Arguments:** | Argument | Description | | --------- | -------------------------------------------- | | `adapter` | (Optional) The adapter to use (e.g., `msw`). | - Currently, only `msw` is supported. **Options:** | Option | Description | | ------------- | ----------------------------------------------------------------------------------- | | `-c, --clean` | Generate brand new mock data and remove all existing mocked data and manifest file. | ## Tool-Agnostic by Design By default, `openapi-mock-gen` is tool-agnostic. It generates two things: 1. **Mock Data**: JS files containing realistic data for your API responses. 2. **Manifest File**: A `manifest.json` file that acts as a map to the generated data. ```json // Example manifest.json { "manifest": [ { "method": "GET", "path": "/users", "operationId": "getUserInfo", "summary": "Get user info", "mockFile": "users-get-user-info.js", "nullablePaths": ["user.email"] } ] } ``` This simple output allows you to integrate the generated mocks with any testing or mocking tool you choose. ### Example: Manual Usage The generated mock files can be used in a pure, manual way to reduce complexity and needs to integrate with other tools if you want. Imagine you have a component that uses a `fetchUser` function to fetch data. You can use Jest/Vitest to mock this function and provide the data generated by `openapi-mock-gen`. ```javascript // src/api.js export async function fetchUser() { const response = await fetch('/api/user'); // ... error handling return response.json(); } ``` In your component's test file, you can mock this module: ```javascript // src/components/UserInfo.test.js import fs from 'fs'; import path from 'path'; import { render, screen, waitFor } from '@testing-library/react'; import UserInfo from './UserInfo'; import { fetchUser } from '../api'; // Tell Jest to use a custom implementation for the `../api` module jest.mock('../api', () => ({ __esModule: true, fetchUser: jest.fn(), })); test('displays user name after fetching', async () => { // 1. Load the manifest to find our mock file const manifestPath = path.resolve(process.cwd(), '.mocks', 'manifest.json'); const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8')); const { mockFile } = manifest.manifest.find(({ path }) => path === '/api/user') || {}; // 2. Dynamically import the mock data from the file path const { default: mockUserData } = await import(path.resolve(process.cwd(), '.mocks', mockFile)); // 3. Provide the loaded data as the mock implementation for `fetchUser` fetchUser.mockResolvedValue(mockUserData); // 4. Render the component that calls `fetchUser` render(<UserInfo />); // The component will receive the mocked data instead of making a real API call await waitFor(() => { expect(screen.getByText(mockUserData.name)).toBeInTheDocument(); }); }); ``` ### Example: Pairing with MSW If you want to use the generated mock data in MSW, you can use the `msw` adapter to auto generate the needed handlers. ```bash npx openapi-mock-gen@latest msw #if you have installed it as a dev dependency openapi-mock-gen msw ``` This will generate the standard mock data and `manifest.json`, plus an additional set of files containing ready-to-use MSW handlers. Including: - `msw/index.js`: The entry point for msw worker or server. - `msw/browser.js`: The browser worker script with the handlers. - `msw/server.js`: The node server script with the handlers. - `msw/handlers.js`: The handlers for the mock data. - `msw/utils.js`: The utils used in the handlers. For how to use the generated handlers, please refer to the [MSW documentation](https://mswjs.io/docs/) or the [MSW official examples](https://github.com/mswjs/examples/tree/main/examples). ## Advanced Configuration The `mock.config.js` file offers powerful ways to control your mock data. ### Custom Data Generation with `fakerMap` Use `fakerMap` to define how specific data fields are generated. You can match fields by string or regex and provide a fixed value, a Faker.js expression, or a custom function. ```javascript // mock.config.mjs import { faker } from '@faker-js/faker'; export default { // ... fakerMap: { // Match by exact key, using a faker expression string id: 'faker.string.uuid()', // Match by exact key, using a function with faker username: () => faker.person.fullName(), // Match by regex, using a fixed value '(?:^|_)image|img|picture(?:_|$)': 'https://picsum.photos/200', // Use a custom function with native JS APIs randomValue: () => Math.random(), }, }; ``` ### Endpoint-Specific Overrides You can override global settings for specific endpoints to handle unique cases. ```javascript // mock.config.mjs export default { // ... // Global setting arrayLength: 5, endpoints: { // Override for a specific endpoint '/api/users': { get: { arrayLength: 20, useExample: false, fakerMap: { // This will override the global fakerMap for this endpoint name: () => 'John Doe', }, }, }, }, }; ``` ## Default Behavior ### Incremental Generation Normally, you would only need to init the config just once. You can then generate the mock data by selecting the desired endpoints you want to mock. New endpoints will be `added` to the manifest file and the mock data directory, while existing endpoints will be `updated` if the `@generated` comment is left intact. ### Working with examples in arrays For a more robust and realistic mock data, `openapi-mock-gen` prioritize `faker` to generate the data `if` the data is inside an array and avoid using the `example` value even if `useExample` is set to `true`. This is to ensure we don't create an array of identical data and potentially break anything. (eg. identical ids in an array cause issue in react) ### The openapi-types.d.ts file This file is auto-generated by `openapi-typescript`. If the type is wrong or a bug is found, please report it to the `openapi-typescript` team. ### Warning about type mismatch If you have `useExample` set to `true`, `openapi-mock-gen` will compare the schema type with the example type and warn you if they don't match. This helps you catch the issue early and avoid potential bugs. ```bash # Example warning output Found id in (GET) - /api/users with schema type string but received example in type: number ``` ## Acknowledgements This project is heavily inspired by and based on [msw-auto-mock](https://www.npmjs.com/package/msw-auto-mock) by zoubingwu. A big thank you to them for their work on the original library. ## License This project is licensed under the MIT License.