{"id":13657390,"url":"https://github.com/ovidiuch/react-mock","last_synced_at":"2025-04-24T01:32:02.345Z","repository":{"id":33153666,"uuid":"149573204","full_name":"ovidiuch/react-mock","owner":"ovidiuch","description":"Declarative mocks for React state and global APIs","archived":true,"fork":false,"pushed_at":"2023-03-28T13:15:22.000Z","size":310,"stargazers_count":365,"open_issues_count":6,"forks_count":8,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-19T08:14:26.224Z","etag":null,"topics":["fetch","mocking","react","state","testing","ui"],"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/ovidiuch.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","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}},"created_at":"2018-09-20T07:59:29.000Z","updated_at":"2025-03-28T18:47:59.000Z","dependencies_parsed_at":"2024-01-28T14:24:31.030Z","dependency_job_id":"ced19b87-ccfe-48d2-8cc2-72d65466bb7a","html_url":"https://github.com/ovidiuch/react-mock","commit_stats":{"total_commits":45,"total_committers":1,"mean_commits":45.0,"dds":0.0,"last_synced_commit":"c33dfa1d6f0c9ce7b3eaba073618d61731a0e82e"},"previous_names":["ovidiuch/react-mock","skidding/react-mock"],"tags_count":19,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ovidiuch%2Freact-mock","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ovidiuch%2Freact-mock/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ovidiuch%2Freact-mock/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ovidiuch%2Freact-mock/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ovidiuch","download_url":"https://codeload.github.com/ovidiuch/react-mock/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250544010,"owners_count":21448023,"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":["fetch","mocking","react","state","testing","ui"],"created_at":"2024-08-02T05:00:41.903Z","updated_at":"2025-04-24T01:32:01.891Z","avatar_url":"https://github.com/ovidiuch.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# React mock\n\n[![Build](https://travis-ci.com/skidding/react-mock.svg?branch=master)](https://travis-ci.com/skidding/react-mock) [![Coverage](https://codecov.io/gh/skidding/react-mock/branch/master/graph/badge.svg)](https://codecov.io/gh/skidding/react-mock)\n\nDeclarative mocks for React state and global APIs.\n\n## Jump to\n\n- **[Why?](#why)**\n- [Component state](#component-state)\n- [Fetch requests](#fetch-requests)\n- [LocalStorage](#localstorage)\n- [XHR requests](#xhr-requests)\n- **[How to contribute](#how-to-contribute)**\n\n## Why?\n\nThe motivation for this project comes from wanting to load any type of React component in isolation—inside automated tests as well as in component explorers such as [Cosmos](https://github.com/react-cosmos/react-cosmos) or [Storybook](https://github.com/storybooks/storybook). Some components as stateful, while others fetch data or interact with some other external input.\n\nThe aim here is to isolate _all_ components, not just presentational and stateless components.\n\n### Declarative\n\nTools like [fetch-mock](http://www.wheresrhys.co.uk/fetch-mock/) and [xhr-mock](https://github.com/jameslnewell/xhr-mock) are already used by many of us in component tests. But they require imperative _setups_ and _teardowns_, which has two drawbacks:\n\n1. They require before/after orchestration in component tests, which is tedious and can create convoluted test cases.\n\n2. They're difficult to integrate in component explorers where a usage file is a declarative component element.\n\nTo overcome these drawbacks, `react-mock` offers mocking techniques as declarative [React elements](https://reactjs.org/docs/rendering-elements.html). Lifecycle methods take care of setting up and reverting mocks behind the hood.\n\n### Composition\n\nTwo or more mocks can be composed into a single React element.\n\n```js\nrender(\n  \u003cLocalStorageMock items={{ userId: 123 }}\u003e\n    \u003cFetchMock matcher=\"/user/123\" response={{ name: 'Jessica' }}\u003e\n      \u003cStateMock state={{ show: true }}\u003e\n        \u003cToggleShow\u003e\n          \u003cUserGreeting /\u003e\n        \u003c/ToggleShow\u003e\n      \u003c/StateMock\u003e\n    \u003c/FetchMock\u003e\n  \u003c/LocalStorageMock\u003e\n);\n```\n\n### Limitations\n\n- Some react-mock components mock a global API entirely, like _fetch_ or _localStorage_. For this reason only one instance of each should be rendered at once. There might be ways to compose these mocks in the future.\n\n- To keep this codebase light, the declarative APIs mirror the params of their underlying APIs. Eg. Although they both mock server requests, the `FetchMock` API is different from the `XhrMock` API because they rely on different libs. More concise interfaces are possible, but they increase the scope of this project.\n\n## Component state\n\nInject React component state declaratively.\n\n\u003e `StateMock` must be the direct parent of the stateful component for the state injection to work.\n\n```js\nimport { StateMock } from '@react-mock/state';\n\nrender(\n  \u003cStateMock state={{ count: 5 }}\u003e\n    \u003cCounter /\u003e\n  \u003c/StateMock\u003e\n);\n```\n\n\u003e **Warning:** StateMock delays ref calls. This means refs can get called _after_ componentDidMount, instead of before as you [might expect](https://stackoverflow.com/questions/44074747/componentdidmount-called-before-ref-callback).\n\n## Fetch requests\n\nA declarative wrapper for the wonderful [fetch-mock](http://www.wheresrhys.co.uk/fetch-mock/).\n\n\u003e **Note:** FetchMock mocks the global Fetch API, so only one FetchMock instance should be rendered at once.\n\n```js\nimport { FetchMock } from '@react-mock/fetch';\n\n// Passing fetch-mock options\nrender(\n  \u003cFetchMock options={{ matcher: '/login', response: 401, method: 'POST' }}\u003e\n    \u003cMyComponent /\u003e\n  \u003c/FetchMock\u003e\n);\n\n// Passing fetch-mock config\nrender(\n  \u003cFetchMock\n    matcher=\"/posts\"\n    response={200}\n    config={{ fallbackToNetwork: true }}\n  \u003e\n    \u003cMyComponent /\u003e\n  \u003c/FetchMock\u003e\n);\n```\n\n### Multiple mocks\n\n```js\nrender(\n  \u003cFetchMock\n    mocks={[\n      { matcher: '/users', response: [{ id: 123 }] },\n      { matcher: '/user/123', response: { name: 'Jessica' } }\n    ]}\n  \u003e\n    \u003cMyComponent /\u003e\n  \u003c/FetchMock\u003e\n);\n```\n\n### Inspection\n\nSee fetch-mock's [inspection methods](http://www.wheresrhys.co.uk/fetch-mock/#api-inspectionfiltering) to check how fetch was called.\n\n\u003e **Note:** Import `fetchMock` from @react-mock/fetch to ensure you're inspecting on the right fetch-mock instance.\n\n```js\nimport { fetchMock } from '@react-mock/fetch';\n\nconst [, { body }] = fetchMock.lastCall('/login', 'POST');\nexpect(JSON.parse(body)).toEqual({ user: 'harry' });\n```\n\n## LocalStorage\n\nMock LocalStorage data declaratively.\n\n\u003e **Note:** LocalStorageMock mocks the global localStorage API, so only one LocalStorageMock instance should be rendered at once.\n\n```js\nimport { LocalStorageMock } from '@react-mock/localstorage';\n\nrender(\n  \u003cLocalStorageMock items={{ sessionId: 're4lt0k3n' }}\u003e\n    \u003cMyComponent /\u003e\n  \u003c/LocalStorageMock\u003e\n);\n```\n\n## XHR requests\n\nA declarative wrapper for the great [xhr-mock](https://github.com/jameslnewell/xhr-mock).\n\n\u003e **Note:** XhrMock mocks the global XMLHttpRequest API, so only one XhrMock instance should be rendered at once.\n\n```js\nimport { XhrMock } from '@react-mock/xhr';\n\n// GET\nrender(\n  \u003cXhrMock\n    url=\"/users\"\n    response={(req, res) =\u003e res.body(JSON.stringify(users))}\n  \u003e\n    \u003cMyComponent /\u003e\n  \u003c/XhrMock\u003e\n);\n\n// POST\nrender(\n  \u003cXhrMock url=\"/login\" method=\"POST\" response={(req, res) =\u003e res.status(401)}\u003e\n    \u003cMyComponent /\u003e\n  \u003c/XhrMock\u003e\n);\n```\n\n### Multiple mocks\n\n```js\nconst res = body =\u003e (req, res) =\u003e res.body(JSON.stringify(body));\n\nrender(\n  \u003cXhrMock\n    mocks={[\n      { url: '/users', response: res([{ id: 123 }]) },\n      { url: '/user/123', response: res({ name: 'Jessica' }) }\n    ]}\n  \u003e\n    \u003cMyComponent /\u003e\n  \u003c/XhrMock\u003e\n);\n```\n\n## How to contribute\n\n### Intention\n\nPlease take a minute to understand this project's purpose and ensure your contribution is thoughtful and relevant. Preserving the integrity of an open source project is hard. Thanks!\n\n### Check your code\n\nYou have the following weapons at your disposal: `yarn lint`, `yarn flow` and `yarn test`. Use them.\n\n### New package\n\nRun `yarn new-package` and you'll follow this friendly flow that will generate initial boilerplate.\n\n![New package](new-package.png)\n\n### Docs\n\nEach package has its own README. This is useful for keeping docs close to code, as well as for showing docs on each package's npm page.\n\n**The root README is generated using a script. Do not edit it by hand.** It's assembled from a [template](scripts/templates/README.md), individual package docs and the CONTRIBUTING.md.\n\nRun `npm generate-readme` to update the root README.\n\n## License\n\nMIT © [Ovidiu Cherecheș](https://ovidiu.ch)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fovidiuch%2Freact-mock","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fovidiuch%2Freact-mock","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fovidiuch%2Freact-mock/lists"}