{"id":20648137,"url":"https://github.com/surveymonkey/graphql-ergonomock","last_synced_at":"2025-04-16T14:40:37.041Z","repository":{"id":37024639,"uuid":"245813491","full_name":"SurveyMonkey/graphql-ergonomock","owner":"SurveyMonkey","description":"Automatic mocking of GraphQL queries","archived":false,"fork":false,"pushed_at":"2025-04-13T09:33:18.000Z","size":446,"stargazers_count":19,"open_issues_count":26,"forks_count":6,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-13T10:32:24.029Z","etag":null,"topics":["apollo","apollo-client","factory","fixtures","graphql","mock","mocking","test","testing"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SurveyMonkey.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-03-08T12:50:45.000Z","updated_at":"2022-09-28T23:34:29.000Z","dependencies_parsed_at":"2023-10-01T15:03:10.203Z","dependency_job_id":"1dd707c3-e93e-438c-8553-fd1d56cea7aa","html_url":"https://github.com/SurveyMonkey/graphql-ergonomock","commit_stats":null,"previous_names":["joual/graphql-ergonomock"],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SurveyMonkey%2Fgraphql-ergonomock","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SurveyMonkey%2Fgraphql-ergonomock/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SurveyMonkey%2Fgraphql-ergonomock/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SurveyMonkey%2Fgraphql-ergonomock/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SurveyMonkey","download_url":"https://codeload.github.com/SurveyMonkey/graphql-ergonomock/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249250973,"owners_count":21237965,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apollo","apollo-client","factory","fixtures","graphql","mock","mocking","test","testing"],"created_at":"2024-11-16T17:06:26.251Z","updated_at":"2025-04-16T14:40:37.018Z","avatar_url":"https://github.com/SurveyMonkey.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n\u003c!-- PROJECT SHIELDS --\u003e\n\u003c!--\n*** I'm using markdown \"reference style\" links for readability.\n*** Reference links are enclosed in brackets [ ] instead of parentheses ( ).\n*** See the bottom of this document for the declaration of the reference variables\n*** for contributors-url, forks-url, etc. This is an optional, concise syntax you may use.\n*** https://www.markdownguide.org/basic-syntax/#reference-style-links\n--\u003e\n[![CircleCI][circleci-shield]][circleci-url]\n[![CodeCov][codecov-shield]][codecov-url]\n[![Contributors][contributors-shield]][contributors-url]\n[![Forks][forks-shield]][forks-url]\n[![Stargazers][stars-shield]][stars-url]\n[![Issues][issues-shield]][issues-url]\n[![Version][version-shield]][version-url]\n[![MIT License][license-shield]][license-url]\n\n\n\n\u003c!-- PROJECT LOGO --\u003e\n\u003cbr /\u003e\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/SurveyMonkey/graphql-ergonomock\"\u003e\n  \u003c/a\u003e\n\n  \u003ch3 align=\"center\"\u003eGraphQL Ergonomock\u003c/h3\u003e\n\n  \u003cp align=\"center\"\u003e\n    🔮 Developer-friendly automagical mocking for GraphQL\n    \u003cbr /\u003e\n    \u003ca href=\"https://github.com/SurveyMonkey/graphql-ergonomock/issues\"\u003eReport Bug\u003c/a\u003e\n    ·\n    \u003ca href=\"https://github.com/SurveyMonkey/graphql-ergonomock/issues\"\u003eRequest Feature\u003c/a\u003e\n  \u003c/p\u003e\n\u003c/p\u003e\n\n\n\n\u003c!-- TABLE OF CONTENTS --\u003e\n## Table of Contents\n\n- [Table of Contents](#table-of-contents)\n- [About The Project](#about-the-project)\n  - [Basic Example](#basic-example)\n  - [Basic Example (Apollo)](#basic-example-apollo)\n  - [Built With](#built-with)\n- [Getting Started](#getting-started)\n  - [Installation](#installation)\n  - [Usage](#usage)\n    - [Default Case](#default-case)\n    - [ErgonoMockedProvider for Use with Apollo-Client](#ergonomockedprovider-for-use-with-apollo-client)\n    - [Providing Functions as Resolver in the Mock Shape](#providing-functions-as-resolver-in-the-mock-shape)\n    - [Mocking Errors](#mocking-errors)\n    - [Mocking Mutations](#mocking-mutations)\n- [API](#api)\n  - [`ergonomock()`](#ergonomock)\n  - [`\u003cErgonoMockedProvider\u003e`](#ergonomockedprovider)\n- [Roadmap](#roadmap)\n- [Contributing](#contributing)\n- [License](#license)\n- [Contact](#contact)\n- [Acknowledgements](#acknowledgements)\n\n\n\n\u003c!-- ABOUT THE PROJECT --\u003e\n## About The Project\n\nThis library provides a developer-friendly method to mock your GraphQL requests. By default, it ships with the following features:\n\n* **Automatic mocking** of types and fields based on schema definition.\n* **Deterministic randomization** of mocked values based on the provided mock shape, to support usage of features such as snapshots.\n* Support for queries using **fragments, unions \u0026 interfaces**.\n* Allows usage of **functions as mock values**, which have the signature of a GraphQL resolver, and are resolved at runtime.\n\n### Basic Example\n\n```js\nimport { ergonomock } from 'graphql-ergonomock';\n\n// Given a particular GraphQL Schema, ...\nconst schema = gql`\n  type Shape {\n    id: ID!\n    returnInt: Int\n    nestedShape: Shape\n    returnBoolean: Boolean\n  }\n\n  type Query {\n    getShape: Shape\n  }\n`;\n\n// ...a GraphQL query, ...\nconst query = gql`\n{\n  getShape {\n    id\n    nestedShape {\n      returnInt\n      nestedShape {\n        returnInt\n        returnBoolean\n      }\n    }\n  }\n}\n`;\n\n// ...and a partial, possibly nested shape of data...\nconst mocks = {\n  getShape: {\n    nestedShape: {\n      returnInt: 5,\n      nestedShape: {\n        returnInt: 10\n      }\n    }\n  }\n};\n\n// ... provides the expected object filled with mock data\nconst resp = ergonomock(schema, query, { mocks });\nexpect(resp.data).toMatchObject({\n  id: expect.toBeString(),\n  nestedShape: {\n    returnInt: 5,\n    nestedShape: {\n      returnInt: 10,\n      returnBoolean: expect.toBeBoolean()\n    }\n  }\n}); // ✅ test pass\n```\n\n### Basic Example (Apollo)\n\n```js\nimport { ErgonoMockedProvider as MockedProvider } from \"graphql-ergonomock\";\n\n// Given a particular GraphQL Schema, ...\nconst schema = gql`\n  type Shape {\n    id: ID!\n    returnString: String\n    returnBoolean: Boolean\n  }\n\n  type Query {\n    getShape: Shape\n  }\n`;\n\n// ...a component making a query ...\nconst QUERY = gql`\nquery MyQuery {\n  getShape {\n    id\n    returnString\n    returnBoolean\n  }\n}\n`;\nconst MyComponent = () =\u003e {\n  const { loading, error, data } = useQuery(QUERY);\n  if (loading) return \u003cp\u003eLoading\u003c/p\u003e;\n  if (error) return \u003cp\u003eError\u003c/p\u003e;\n\n  return (\n    \u003cdiv\u003e\n      MyComponent.\n      \u003cdiv\u003eString: {data.getShape.returnString}\u003c/div\u003e\n      \u003cdiv\u003eBoolean: {data.getShape.returnBoolean.toString()}\u003c/div\u003e\n    \u003c/div\u003e\n  );\n};\n\ntest(\"MyComponent can render the query results.\", async () =\u003e {\n  const mocks = {\n    MyQuery: {\n      getShape: { returnString: \"John Doe\" }\n    }\n  };\n  const { findByText } = render(\n    \u003cMockedProvider schema={schema} mocks={mocks}\u003e\n      \u003cMyComponent /\u003e\n    \u003c/MockedProvider\u003e\n  );\n  expect(await findByText(/String: John Doe/)).toBeVisible();\n  expect(await findByText(/Boolean: (true|false)/)).toBeVisible();\n}); // ✅ test pass\n```\n\n### Built With\n* [Typescript](https://www.typescriptlang.org/)\n* [GraphQL](https://graphql.org)\n* [Jest](https://jestjs.io)\n\n\n\n\u003c!-- GETTING STARTED --\u003e\n## Getting Started\n\n### Installation\n\n```shell\nnpm i graphql-ergonomock --save-dev\n```\n\n\u003c!-- USAGE EXAMPLES --\u003e\n### Usage\n\n#### Default Case\nThe `ergonomock()` function can be used on its own to create mock responses out of GraphQL queries.\n\n\u003cdetails\u003e\n\u003csummary\u003eSee example\u003c/summary\u003e\n\u003cp\u003e\n\n```js\nimport { ergonomock } from 'graphql-ergonomock';\nimport schema from '../my-schema.graphql';\n\ntest(\"I can mock a response\", () =\u003e {\n  const resp = ergonomock(schema, 'query MyCrucialOperation { car { id, plateNumber } }', {\n    mocks: { car: { plateNumber: '123abc' } }\n  });\n\n  expect(resp).toMatchObject({\n    data: {\n      car: {\n        id: expect.toBeString(),\n        plateNumber: '123abc'\n      }\n    }\n  });\n});\n```\n\u003c/p\u003e\n\u003c/details\u003e\n\n#### ErgonoMockedProvider for Use with Apollo-Client\n\nIf your app uses Apollo-Client, you can also use `ErgonoMockedProvider` which wraps `ergonomock()`. The generated values are stable \u0026 deterministic based on the query name, shape, and variables (this is so you can leverage testing snapshots if you are so inclined).\n\n\u003cdetails\u003e\n\u003csummary\u003eSee example\u003c/summary\u003e\n\u003cp\u003e\n\n```jsx\nimport { ErgonoMockedProvider as MockedProvider } from 'graphql-ergonomock';\nimport schema from '../my-schema.graphql';\n\ntest(\"I can mock a response\", () =\u003e {\n  const mocks = {\n    MyCrucialOperation: {\n      car: { plateNumber: '123abc' }\n    }\n  };\n  const { findByText } = render(\n    \u003cMockedProvider schema={schema} mocks={mocks}\u003e\n      \u003cMyApp /\u003e\n    \u003c/MockedProvider\u003e\n  );\n  expect(await findByText(/'123abc'/)).toBeVisible();\n});\n```\n\u003c/p\u003e\n\u003c/details\u003e\n\nIf a particular component is called multiple times in the React tree (but with different variables), you can provide a function as value for an operation, and the function will be called with the `operation: GraphQLOperation` as first and only argument.\n\u003cbr /\u003e\n\u003cdetails\u003e\n\u003csummary\u003eSee example\u003c/summary\u003e\n\u003cp\u003e\n\n```jsx\nimport { ErgonoMockedProvider as MockedProvider } from 'graphql-ergonomock';\nimport schema from '../my-schema.graphql';\n\ntest(\"I can mock a response with a function\", () =\u003e {\n  let cardinality = 0;\n  const mocks = {\n    MyCrucialOperation: (operation) =\u003e ({ plateNumber: `aaa00${cardinality++}` })\n  };\n  const { findAllByText } = render(\n    \u003cMockedProvider schema={schema} mocks={mocks}\u003e\n      \u003cMyApp /\u003e\n    \u003c/MockedProvider\u003e\n  );\n  expect(await findAllByText(/'aaa00'/)).toHaveLength(3);\n});\n```\n\u003c/p\u003e\u003c/details\u003e\n\nFinally, you can spy on executed operations via the `onCall` prop.\n\u003cbr /\u003e\n\u003cdetails\u003e\n\u003csummary\u003eSee example\u003c/summary\u003e\u003cp\u003e\n\n```jsx\nconst spy = jest.fn();\nconst { findByText } = render(\n  \u003cMockedProvider schema={schema} onCall={spy}\u003e\n    \u003cMyComponent id=\"1\" /\u003e\n    \u003cMyComponent id=\"2\" /\u003e\n    \u003cMyComponent id=\"3\" /\u003e\n  \u003c/MockedProvider\u003e\n);\n\n//...\nexpect(spy.mock.calls).toHaveLength(3);\nconst { operation, response } = spy.mock.calls[0][0];\nexpect(operation.variables.id).toEqual(\"1\");\n```\n\u003c/p\u003e\u003c/details\u003e\n\n\n\n\n#### Providing Functions as Resolver in the Mock Shape\n\nYou can use functions for any part of the nested mock, and it will be used as a resolver for this field. The typical signature for a resolver is `(root, args, context, info) =\u003e any`.\n\n\u003cdetails\u003e\n\u003csummary\u003eSee example\u003c/summary\u003e\u003cp\u003e\n\n```js\n// ...\nconst mocks = {\n  returnShape: {\n    returnInt: 4321,\n    nestedShape: (root: any, args: any, ctx: any, info: any) =\u003e {\n      return {\n        returnInt: root.someField ? 1234 : 5678\n      };\n    }\n  }\n}\n//...\n```\n\u003c/p\u003e\u003c/details\u003e\n\n\n#### Providing default mock resolver functions\n\nIf you have custom scalar types or would like to provide default mock resolver functions for certain types, you can pass your mock functions via the `resolvers` option.\n\n\u003cdetails\u003e\n\u003csummary\u003eSee example\u003c/summary\u003e\u003cp\u003e\n\n```js\nconst schema = gql`\n  type Shape = {\n    id: ID!\n    returnInt: Int\n    date: Date\n    nestedShape: Shape\n  }\n\n  type Query {\n    getShape: Shape\n  }\n`;\n\nconst testQuery = gql`\n{\n  getShape {\n    id\n    returnInt\n    date\n    nestedShape {\n      date\n    }\n  }\n}\n`;\n\nconst resp = ergonomock(schema, testQuery, {\n  resolvers: {\n    Date: () =\u003e \"2021-04-09\"\n  }\n});\nexpect(resp.data).toMatchObject({\n  id: expect.toBeString(),\n  returnInt: expect.toBeNumber(),\n  date: '2021-04-09'\n  nestedShape {\n    date: '2021-04-09'\n  }\n});\n```\n\u003c/p\u003e\u003c/details\u003e\n\n#### Mocking Errors\n\nYou can return or throw errors within the mock shape.\n\n\u003cdetails\u003e\n\u003csummary\u003eSee example\u003c/summary\u003e\u003cp\u003e\n\n```js\nconst testQuery = gql`\n  {\n    getCar {\n      id\n    }\n  }\n`;\n\nconst resp = ergonomock(schema, testQuery, {\n  mocks: {\n    getCar: () =\u003e { throw new Error(\"Server Error\"); }\n    // or simply getCar: new Error(\"Server Error\")\n  }\n});\n\nconsole.log(resp.data.getCar); // null\nconsole.log(resp.errors[0]); // { message: \"Server Error\", ...}\n```\n\u003c/p\u003e\u003c/details\u003e\n\n\n#### Mocking Mutations\n\nYou can mock mutations, but if you are using `ergonomock()` directly, you'll have to provide the correct variables for the operation in order for it to not fail.\n\n\u003cdetails\u003e\n\u003csummary\u003eSee example\u003c/summary\u003e\u003cp\u003e\n\n```jsx\ntest(\"Can partially mock mutations\", () =\u003e {\n  const query = /* GraphQL */ `\n    mutation SampleQuery($input: ShapeInput!) {\n      createShape(input: $input) {\n        id\n        returnInt\n        returnString\n      }\n    }\n  `;\n\n  const resp: any = ergonomock(schema, query, {\n    mocks: {\n      createShape: { id: \"567\" }\n    },\n    variables: {\n      input: { someID: \"123\", someInt: 123 }\n    }\n  });\n\n  expect(resp.data.createShape).toMatchObject({\n    id: \"567\",\n    returnInt: expect.toBeNumber(),\n    returnString: expect.toBeString()\n  });\n});\n```\n\u003c/p\u003e\u003c/details\u003e\n\n\n## API\n\n### `ergonomock()`\n\nThe `ergonomock(schema, query, options)` function takes 3 arguments\n\n1. _(required)_ A GraphQL **schema** (not in SDL form).\n2. _(required)_ A GraphQL **query**, either in SDL (string) form, or `DocumentNode`.\n3. _(optional)_ An option object.\n   1. `mocks` is an object that can partially or fully match the expected response shape.\n   2. `seed` is a string used to seed the random number generator for automocked values.\n   3. `variables` is the variable values object used in the query or mutation.\n\n\n### `\u003cErgonoMockedProvider\u003e`\n\nThis component's props are very similar to Apollo-Client's [MockedProvider](https://www.apollographql.com/docs/react/api/react-testing/#mockedprovider). The only differences are:\n\n- `mocks` is an object where keys are the operation names and the values are the `mocks` input that `ergonomock()` would accept. (i.e. could be empty, or any shape that matches the expected response.)\n- `onCall` is a handler that gets called by any executed query. The call signature is `({operation: GraphQLOperation, response: any}) =\u003e void` where response is the full response being returned to that single query. The purpose of `onCall` is to provide some sort of spy (or `jest.fn()`) to make assertions on which calls went through, with which variables, and get a handle on the generated values from `ergonomock()`.\n- `resolvers` is an object where the keys are the `gql` type and the values are the mock resolver functions. It's designed to allow users to override or provide a default mock function for certain types. (e.g. custom scalar types) The call signature is `(root, args, context, info) =\u003e any`.\n\n\u003c!-- ROADMAP --\u003e\n## Roadmap\n\nSee the [open issues](https://github.com/SurveyMonkey/graphql-ergonomock/issues) for a list of proposed features (and known issues).\n\n\n\u003c!-- CONTRIBUTING --\u003e\n## Contributing\n\nContributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**.\n\n1. Fork the Project\n2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)\n3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)\n4. Push to the Branch (`git push origin feature/AmazingFeature`)\n5. Open a Pull Request\n\n\n\n\u003c!-- LICENSE --\u003e\n## License\n\nDistributed under the MIT License. See `LICENSE` for more information.\n\n\n\u003c!-- CONTACT --\u003e\n## Contact\n\nMaintainer: Joel Marcotte (Github [@joual](https://github.com/joual))\n\nProject Link: [https://github.com/SurveyMonkey/graphql-ergonomock](https://github.com/SurveyMonkey/graphql-ergonomock)\n\n\n\u003c!-- ACKNOWLEDGEMENTS --\u003e\n## Acknowledgements\n\n* [A new approach to mocking GraphQL Data](https://www.freecodecamp.org/news/a-new-approach-to-mocking-graphql-data-1ef49de3d491/)\n* [GraphQL-Tools](https://github.com/apollographql/graphql-tools)\n* [GraphQL-JS](https://github.com/graphql/graphql-js)\n\n\n\u003c!-- MARKDOWN LINKS \u0026 IMAGES --\u003e\n\u003c!-- https://www.markdownguide.org/basic-syntax/#reference-style-links --\u003e\n[contributors-shield]: https://img.shields.io/github/contributors/SurveyMonkey/graphql-ergonomock.svg?style=flat-square\n[contributors-url]: https://github.com/SurveyMonkey/graphql-ergonomock/graphs/contributors\n[forks-shield]: https://img.shields.io/github/forks/SurveyMonkey/graphql-ergonomock.svg?style=flat-square\n[forks-url]: https://github.com/SurveyMonkey/graphql-ergonomock/network/members\n[stars-shield]: https://img.shields.io/github/stars/SurveyMonkey/graphql-ergonomock.svg?style=flat-square\n[stars-url]: https://github.com/SurveyMonkey/graphql-ergonomock/stargazers\n[version-url]:https://www.npmjs.com/package/graphql-ergonomock\n[version-shield]:https://img.shields.io/npm/v/graphql-ergonomock.svg?style=flat-square\n[issues-shield]: https://img.shields.io/github/issues/SurveyMonkey/graphql-ergonomock.svg?style=flat-square\n[issues-url]: https://github.com/SurveyMonkey/graphql-ergonomock/issues\n[license-shield]: https://img.shields.io/github/license/SurveyMonkey/graphql-ergonomock.svg?style=flat-square\n[license-url]: https://github.com/SurveyMonkey/graphql-ergonomock/blob/master/LICENSE.txt\n[circleci-shield]: https://circleci.com/gh/SurveyMonkey/graphql-ergonomock.svg?style=shield\n[circleci-url]: https://app.circleci.com/pipelines/github/SurveyMonkey/graphql-ergonomock\n[codecov-shield]: https://codecov.io/gh/SurveyMonkey/graphql-ergonomock/branch/master/graph/badge.svg\n[codecov-url]: https://codecov.io/gh/SurveyMonkey/graphql-ergonomock\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsurveymonkey%2Fgraphql-ergonomock","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsurveymonkey%2Fgraphql-ergonomock","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsurveymonkey%2Fgraphql-ergonomock/lists"}