{"id":15384023,"url":"https://github.com/rwieruch/react-apollo-async-testing","last_synced_at":"2025-10-11T12:38:27.718Z","repository":{"id":70925785,"uuid":"131117008","full_name":"rwieruch/react-apollo-async-testing","owner":"rwieruch","description":"A lightweight way to test your Mutation and Query components in React Apollo (react-apollo).","archived":false,"fork":false,"pushed_at":"2018-10-25T04:46:39.000Z","size":250,"stargazers_count":10,"open_issues_count":2,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-09-28T14:57:42.131Z","etag":null,"topics":["apollo-client","apollo-client-testing","react","react-apollo","react-apollo-testing"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/rwieruch.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2018-04-26T07:27:46.000Z","updated_at":"2022-06-10T11:12:30.000Z","dependencies_parsed_at":"2023-04-06T18:21:47.289Z","dependency_job_id":null,"html_url":"https://github.com/rwieruch/react-apollo-async-testing","commit_stats":{"total_commits":18,"total_committers":1,"mean_commits":18.0,"dds":0.0,"last_synced_commit":"781bcb35dfd598d20b227b30cbe6e9d7a9b8b205"},"previous_names":["rwieruch/react-apollo-testing"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rwieruch/react-apollo-async-testing","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rwieruch%2Freact-apollo-async-testing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rwieruch%2Freact-apollo-async-testing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rwieruch%2Freact-apollo-async-testing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rwieruch%2Freact-apollo-async-testing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rwieruch","download_url":"https://codeload.github.com/rwieruch/react-apollo-async-testing/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rwieruch%2Freact-apollo-async-testing/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279007167,"owners_count":26084247,"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","status":"online","status_checked_at":"2025-10-11T02:00:06.511Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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-client","apollo-client-testing","react","react-apollo","react-apollo-testing"],"created_at":"2024-10-01T14:40:24.143Z","updated_at":"2025-10-11T12:38:27.713Z","avatar_url":"https://github.com/rwieruch.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# react-apollo-async-testing\n\n**Beta:** A lightweight way to test your Mutation and Query components in React Apollo ([react-apollo](https://github.com/apollographql/react-apollo)).\n\n## Install \u0026 Usage\n\nOn the command line:\n\n`npm install --save-dev react-apollo-async-testing`\n\nThe following test examples showcase this library by using [Jest](https://facebook.github.io/jest/) as assertion and test runner library and [Enzyme](http://airbnb.io/enzyme/) for the actual component renderings and utilities. But Enzyme can be replaced by [react-test-renderer](https://www.npmjs.com/package/react-test-renderer) as well.\n\n### API:\n\n```javascript\n// creates a Apollo Client with sensible defaults (e.g. apollo-cache-inmemory, apollo-http-link)\n// just an optional function, you can create your own Apollo Client instance too\n// afterward, client instance can be used in the ApolloProvider\nconst client = createApolloClient('https://api.github.com/graphql');\n\n// enables GraphQL API mocking\n// define the GraphQL endpoint URI\n// specify a payload object which has a query (and optional variables and operation name)\n// specify a result which you would expect from this query\nconst promise = stubQueryWith(uri, payload, result);\n\n// injects a spied function into the Mutation(s) component(s)\n// check sinon library API to interact with the spy\nconst sinonSpy = injectSpyInMutation();\n```\n\n### Query Testing:\n\nThe desired goal is to keep you in control of **what data** should be returned for **which request**. In addition, you need to be in charge to **mimic the different stages** of the request by having control over a promise (e.g. pending request, resolved request).\n\n**In your application:**\n\n```javascript\nimport React from 'react';\nimport gql from 'graphql-tag';\nimport { Query } from 'react-apollo';\n\nimport Repository from './Repository';\n\nexport const GET_REPOSITORIES_OF_VIEWER = gql`\n  {\n    viewer {\n      name\n      repositories(last: 25) {\n        edges {\n          node {\n            id\n            name\n            url\n            viewerSubscription\n          }\n        }\n      }\n    }\n  }\n`;\n\nconst App = () =\u003e (\n  \u003cQuery query={GET_REPOSITORIES_OF_VIEWER}\u003e\n    {({ data, loading, error }) =\u003e {\n      const { viewer } = data;\n\n      if (loading) {\n        return \u003cdiv data-test-id=\"loading\"\u003eLoading ...\u003c/div\u003e;\n      }\n\n      if (error) {\n        return \u003cdiv data-test-id=\"error\"\u003eError ...\u003c/div\u003e;\n      }\n\n      if (!viewer) {\n        return \u003cdiv data-test-id=\"no-data\"\u003eNo data ...\u003c/div\u003e;\n      }\n\n      return (\n        \u003cdiv\u003e\n          \u003cdiv data-test-id=\"profile\"\u003e{viewer.name}\u003c/div\u003e\n          \u003cul\u003e\n            {viewer.repositories.edges.map(({ node }) =\u003e (\n              \u003cli key={node.id}\u003e\n                \u003cRepository repository={node} /\u003e\n              \u003c/li\u003e\n            ))}\n          \u003c/ul\u003e\n        \u003c/div\u003e\n      );\n    }}\n  \u003c/Query\u003e\n);\n\nexport default App;\n```\n\n**In your test:**\n\n```javascript\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport { ApolloProvider } from 'react-apollo';\n\nimport { mount } from 'enzyme';\nimport {\n  createApolloClient,\n  stubQueryWith,\n} from 'react-apollo-async-testing';\n\nimport App, { GET_REPOSITORIES_OF_VIEWER } from './App';\n\nlet client;\nlet promise;\n\nconst viewerWithRepositories = {\n  viewer: {\n    name: 'Robin Wieruch',\n    repositories: {\n      edges: [\n        {\n          node: {\n            id: '1',\n            name: 'bar',\n            url: 'https://bar.com',\n            viewerSubscription: 'UNSUBSCRIBED',\n          },\n        },\n        {\n          node: {\n            id: '2',\n            name: 'qwe',\n            url: 'https://qwe.com',\n            viewerSubscription: 'UNSUBSCRIBED',\n          },\n        },\n      ],\n    },\n  },\n};\n\nbeforeAll(() =\u003e {\n  promise = stubQueryWith(\n    'https://api.github.com/graphql',\n    {\n      query: GET_REPOSITORIES_OF_VIEWER,\n    },\n    viewerWithRepositories,\n  );\n\n  client = createApolloClient('https://api.github.com/graphql');\n});\n\nafterAll(() =\u003e {\n  // since the fetch API is stubbed with the library\n  // it has to be restored after the tests\n  fetch.restore();\n});\n\ntest('query result of Query component', done =\u003e {\n  const wrapper = mount(\n    \u003cApolloProvider client={client}\u003e\n      \u003cApp /\u003e\n    \u003c/ApolloProvider\u003e,\n  );\n\n  expect(wrapper.find('[data-test-id=\"loading\"]')).toHaveLength(1);\n\n  promise.then().then(() =\u003e {\n    setImmediate(() =\u003e {\n      wrapper.update();\n\n      expect(wrapper.find('[data-test-id=\"profile\"]')).toHaveLength(\n        1,\n      );\n      expect(wrapper.find('[data-test-id=\"profile\"]').text()).toEqual(\n        viewerWithRepositories.viewer.name,\n      );\n\n      done();\n    });\n  });\n});\n```\n\n### Mutation Testing:\n\nThe desired goal is to **have a spied function which is used within the Mutation component**'s children as a function to execute the actual mutation. Only then it is possible to make assertions for the executed mutation.\n\n**In your application:**\n\n```javascript\nimport React from 'react';\nimport gql from 'graphql-tag';\nimport { Mutation } from 'react-apollo';\n\nexport const WATCH_REPOSITORY = gql`\n  mutation($id: ID!, $viewerSubscription: SubscriptionState!) {\n    updateSubscription(\n      input: { state: $viewerSubscription, subscribableId: $id }\n    ) {\n      subscribable {\n        id\n        viewerSubscription\n      }\n    }\n  }\n`;\n\nconst VIEWER_SUBSCRIPTIONS = {\n  SUBSCRIBED: 'SUBSCRIBED',\n  UNSUBSCRIBED: 'UNSUBSCRIBED',\n};\n\nconst isWatch = viewerSubscription =\u003e\n  viewerSubscription === VIEWER_SUBSCRIPTIONS.SUBSCRIBED;\n\nconst Repository = ({\n  repository: { id, url, name, viewerSubscription },\n}) =\u003e (\n  \u003cdiv\u003e\n    \u003ca href={url}\u003e{name}\u003c/a\u003e\n\n    \u003cMutation\n      mutation={WATCH_REPOSITORY}\n      variables={{\n        id,\n        viewerSubscription: isWatch(viewerSubscription)\n          ? VIEWER_SUBSCRIPTIONS.UNSUBSCRIBED\n          : VIEWER_SUBSCRIPTIONS.SUBSCRIBED,\n      }}\n    \u003e\n      {updateSubscription =\u003e (\n        \u003cbutton type=\"button\" onClick={updateSubscription}\u003e\n          {isWatch(viewerSubscription) ? 'Unwatch' : 'Watch'}\n        \u003c/button\u003e\n      )}\n    \u003c/Mutation\u003e\n  \u003c/div\u003e\n);\n\nexport default Repository;\n```\n\n**In your test:**\n\n```javascript\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport { ApolloProvider } from 'react-apollo';\n\nimport { mount } from 'enzyme';\nimport {\n  createApolloClient,\n  injectSpyInMutation,\n} from 'react-apollo-async-testing';\n\nimport Repository, { WATCH_REPOSITORY, isWatch } from './Repository';\n\nlet client;\nlet sinonSpy;\n\nbeforeAll(() =\u003e {\n  sinonSpy = injectSpyInMutation();\n\n  client = createApolloClient('https://api.github.com/graphql');\n});\n\ntest('interaction with mutation function from the Mutation component', () =\u003e {\n  const repository = {\n    id: '1',\n    name: 'foo',\n    url: 'https://foo.com',\n    viewerSubscription: 'UNSUBSCRIBED',\n  };\n\n  const wrapper = mount(\n    \u003cApolloProvider client={client}\u003e\n      \u003cRepository repository={repository} /\u003e\n    \u003c/ApolloProvider\u003e,\n  );\n\n  wrapper.find('button').simulate('click');\n\n  expect(sinonSpy.calledOnce).toEqual(true);\n\n  const expectedObject = {\n    mutation: WATCH_REPOSITORY,\n    variables: {\n      id: repository.id,\n      viewerSubscription: 'SUBSCRIBED',\n    },\n  };\n\n  expect(sinonSpy.calledWith(expectedObject)).toEqual(true);\n});\n```\n\n## Example\n\nA simple example application which uses tested Mutation and Query components can be found in the *example/* folder.\n\n### Install:\n\n* `git clone git@github.com:rwieruch/react-apollo-async-testing.git`\n* `cd react-apollo-async-testing/example`\n* `npm install`\n\n### Run tests:\n\n* `npm test`\n\n### Run application:\n\n* [add your own REACT_APP_GITHUB_PERSONAL_ACCESS_TOKEN in .env file](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/)\n  * scopes/permissions you need to check: admin:org, repo, user, notifications\n* `npm start`\n* visit `http://localhost:3000`","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frwieruch%2Freact-apollo-async-testing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frwieruch%2Freact-apollo-async-testing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frwieruch%2Freact-apollo-async-testing/lists"}