{"id":25794374,"url":"https://github.com/ver0-project/react-hooks-testing","last_synced_at":"2025-02-27T13:58:36.899Z","repository":{"id":275682473,"uuid":"924795055","full_name":"ver0-project/react-hooks-testing","owner":"ver0-project","description":"🧪 Test your react hooks with ease!","archived":false,"fork":false,"pushed_at":"2025-02-20T00:55:45.000Z","size":1398,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-20T01:37:14.825Z","etag":null,"topics":["hooks","react","ssr","testing"],"latest_commit_sha":null,"homepage":"","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/ver0-project.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":"2025-01-30T17:02:37.000Z","updated_at":"2025-02-20T00:55:44.000Z","dependencies_parsed_at":null,"dependency_job_id":"2e3971e1-c897-4ab2-a4b3-ef9766343f40","html_url":"https://github.com/ver0-project/react-hooks-testing","commit_stats":null,"previous_names":["ver0-project/react-hooks-testing"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ver0-project%2Freact-hooks-testing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ver0-project%2Freact-hooks-testing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ver0-project%2Freact-hooks-testing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ver0-project%2Freact-hooks-testing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ver0-project","download_url":"https://codeload.github.com/ver0-project/react-hooks-testing/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241021540,"owners_count":19895661,"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":["hooks","react","ssr","testing"],"created_at":"2025-02-27T13:58:36.412Z","updated_at":"2025-02-27T13:58:36.890Z","avatar_url":"https://github.com/ver0-project.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\u003ch1\u003e@ver0/react-hooks-testing\u003c/h1\u003e\n\n[![NPM Version](https://img.shields.io/npm/v/%40ver0%2Freact-hooks-testing?style=flat-square)](https://www.npmjs.com/package/@ver0/react-hooks-testing)\n[![NPM Downloads](https://img.shields.io/npm/dm/%40ver0%2Freact-hooks-testing?style=flat-square)](https://www.npmjs.com/package/@ver0/react-hooks-testing)\n[![Dependents (via libraries.io), scoped npm package](https://img.shields.io/librariesio/dependents/npm/%40ver0/react-hooks-testing?style=flat-square)](https://www.npmjs.com/package/@ver0/react-hooks-testing)\n[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/ver0-project/react-hooks-testing/ci.yml?style=flat-square)](https://github.com/ver0-project/react-hooks-testing/actions)\n[![Codecov](https://img.shields.io/codecov/c/github/ver0-project/react-hooks-testing?token=Y2K96S71RH\u0026style=flat-square)](https://app.codecov.io/gh/ver0-project/react-hooks-testing)\n[![NPM Type Definitions](https://img.shields.io/npm/types/%40ver0%2Freact-hooks-testing?style=flat-square)](https://www.npmjs.com/package/@ver0/react-hooks-testing)\n\n\u003cp\u003e\u003cbr/\u003e🧪 Test your React hooks with ease!\u003c/p\u003e\n\u003c/div\u003e\n\n### Features\n\n- ✅ Supports React 19.\n- ✅ Server-Side Rendering (SSR) support.\n- ✅ Easy-to-use API.\n- ✅ Errors reporting, even for SSR.\n- ✅ Compatible with any testing framework.\n\n### Why this package exists?\n\nIn May 2022, [\n`@testing-library/react-hooks`](https://github.com/testing-library/react-hooks-testing-library/issues/849)\nwas announced as deprecated, leaving its users locked to React 17. The so-called \"merge\" with\n`@testing-library/react` was never fully realized, as the provided `renderHook` offers only a\nfraction of the functionality that `@testing-library/react-hooks` had, and it completely lacks SSR\nsupport.\n\nI had hoped that the release of React 19 and server components would bring changes, but nothing has\nimproved despite React 19 being in RC for almost a year before its release. When asking about SSR\nsupport, the response is often to resolve the issues independently.\n\nThis package was created to meet the needs of the hooks library I have been developing. I encourage\neveryone to contribute and help make hooks testing simple again. This package offers improved\ntypings compared to `@testing-library/react-hooks`, is testing-framework agnostic, supports SSR, and\nis easy to use.\n\n### Dependencies and compatibility\n\nThis package aims to be compatible only with the current major version of React. Additionally,\nit encourages the use of newer React APIs, such as completely ditching synchronous rendering\nand support of synchronous `act` behavior, as React documentation states it will\nbe [deprecated in future releases](https://react.dev/reference/react/act#await-act-async-actfn).\n\n### How to use\n\nSince the library is designed to be testing-framework agnostic, it does not have any automatic setup\nand therefore requires a tiny bit of pre-configuration to work with your testing framework. I'm\nusing `vitest` and will provide examples for it, but all known frameworks have similar setup\nfunctionality.\n\nAs this library is tested through testing other hooks, following configuration is applied to this\nrepository and can be used as an example.\n\n#### Setup\n\nAfter adding `@ver0/react-hooks-testing` to your dev-dependencies, create a file with the following\ncontent and add it to your test runner configuration as a global setup file.\n\n```ts filename=\"react-hooks.test.ts\"\nimport {hooksCleanup} from \"@ver0/react-hooks-testing\";\nimport {afterEach} from 'vitest';\n\nafterEach(hooksCleanup);\n```\n\n```ts filename=\"vitest.config.ts\"\nimport {defineConfig} from 'vitest/config';\n\nexport default defineConfig({\n\ttest: {\n\t\tdir: './src',\n\t\tsetupFiles: [\n\t\t\t'./src/tests/setup/react-hooks.test.ts',\n\t\t],\n\t},\n});\n```\n\nOr, if you don't have many hooks to test, add it directly to your test files.\n\nAll this code does - unmounts all rendered hooks after each test, so you don't have to worry about\nit yourself.\n\n#### Testing client-side hooks\n\n`renderHook` function made close to `@testing-library/react` API-wise, but with several differences,\nthat are dictated by `act` function.\n\nThe `act` function provided by this library is similar to the one from `react`, but with stricter\ntypings. It only allows async functions to be passed to it, ensuring it always returns a promise,\nwhich should be awaited. This is in line with the React documentation,\nwhich [states](https://react.dev/reference/react/act#await-act-async-actfn) that synchronous\n`act` will be deprecated in future releases.\n\nAdditionally, this `act` function bypasses\nthe [console error](https://react.dev/reference/react/act#error-the-current-testing-environment-is-not-configured-to-support-act)\nregarding the testing environment configuration. Since you're using this library to test hooks,\nyou're already in a testing environment, making this error redundant.\n\n```ts filename=\"useState.test.ts\"\nimport {expect, test} from \"vitest\";\nimport {act, renderHook} from \"@ver0/react-hooks-testing\";\n\ntest('should use setState value', async () =\u003e {\n\tconst {result} = await renderHook(() =\u003e useState('foo'))\n\n\texpect(result.value).toBe(\"foo\")\n\texpect(result.error).toBe(undefined)\n\n\tif (result.value === undefined) {\n\t\treturn;\n\t}\n\n\tawait act(async () =\u003e {\n\t\tresult.value[1]('bar')\n\t})\n\n\texpect(result.value[0]).toBe('bar')\n})\n```\n\nAs you can see in above example - `renderHook` function is asynchronous, reason for that is React's\nrequest to perform any rendering within the `act` function.\n\nIn contrast to `@testing-library/react`, result object has the following type definition:\n\n```ts\n/**\n * Represents the result of rendering a hook.\n */\nexport type ResultValue\u003cT\u003e = {\n\treadonly value: undefined;\n\treadonly error: Error;\n} | {\n\treadonly value: T;\n\treadonly error: undefined;\n}\n\n/**\n * Represents the last rendered hook result and all previous results.\n */\nexport type ResultValues\u003cT\u003e = ResultValue\u003cT\u003e \u0026 {\n\treadonly all: ResultValue\u003cT\u003e[];\n}\n```\n\nThe render results history is accessible via the `all` property, which contains every rendering\nresult as well as the value of the latest render. Unlike `@testing-library/react`, which collects\nresults during the effect phase, this library populates the results during the render phase - it\nallows to ensure tested hook results correctness throughout each render.\n\nAnother notable difference is the `error` property. This property captures any error thrown during\nthe hook’s rendering, thanks to an Error Boundary component wrapped around the hook’s harness\ncomponent.\n\nEach result object is immutable and contains either a `value` or an `error` property—but never both.\nThe hook’s result object follows the same principle. Although the `value` and `error` properties are\nimplemented as getters and always exist, the values they return correspond to the most recent render\nresult from the `all` array.\n\nOtherwise, the API is similar to `@testing-library/react`. Note that the `waitForNextUpdate`\nfunction is not provided, as modern testing frameworks include their own `waitFor` function, which\nserves the same purpose.\n\n#### Testing server-side hooks\n\nThe primary purpose of this package is to provide out-of-the-box SSR (Server-Side Rendering) support\nthrough the `renderHookServer` function. This function works similarly to `renderHook` but includes\na few key differences:\n\n- **Initial Render:** The initial render is performed using React's `renderToString` function.\n- **Hydration:** The hook's render result includes an extra `hydrate` function that hydrates the\n\thook after the initial render.\n- **DOM Root Creation:** The client-side DOM root is created only when the `hydrate` function is\n\tcalled, facilitating testing in a server environment.\n- **Rerenders:** Rerenders are only possible after hydration.\n\nOtherwise, usage is similar to `renderHook`, so dedicated examples are not provided. For usage\nexamples, refer to the `*.ssr.test.ts` files in this repository.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fver0-project%2Freact-hooks-testing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fver0-project%2Freact-hooks-testing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fver0-project%2Freact-hooks-testing/lists"}