{"id":13595023,"url":"https://github.com/danielroe/nuxt-vitest","last_synced_at":"2025-04-09T10:32:40.003Z","repository":{"id":65019735,"uuid":"564076670","full_name":"danielroe/nuxt-vitest","owner":"danielroe","description":"An vitest environment with support for testing code that needs a Nuxt runtime environment","archived":true,"fork":false,"pushed_at":"2023-12-19T16:02:30.000Z","size":1395,"stargazers_count":370,"open_issues_count":4,"forks_count":41,"subscribers_count":14,"default_branch":"main","last_synced_at":"2024-11-06T17:44:51.318Z","etag":null,"topics":["nuxt","nuxt-module","testing","unit-testing","vitest"],"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/danielroe.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"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":"2022-11-10T00:02:15.000Z","updated_at":"2024-08-23T01:13:35.000Z","dependencies_parsed_at":"2023-10-11T05:25:44.918Z","dependency_job_id":"312e15d2-7d27-4daa-bccf-ed78e8ff22ea","html_url":"https://github.com/danielroe/nuxt-vitest","commit_stats":{"total_commits":127,"total_committers":8,"mean_commits":15.875,"dds":0.6220472440944882,"last_synced_commit":"51c003397869a54e65780fa6b6da6d496752ebdd"},"previous_names":["danielroe/vitest-environment-nuxt","nuxt/nuxt-vitest","danielroe/nuxt-vitest"],"tags_count":47,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielroe%2Fnuxt-vitest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielroe%2Fnuxt-vitest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielroe%2Fnuxt-vitest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielroe%2Fnuxt-vitest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/danielroe","download_url":"https://codeload.github.com/danielroe/nuxt-vitest/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248020593,"owners_count":21034459,"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":["nuxt","nuxt-module","testing","unit-testing","vitest"],"created_at":"2024-08-01T16:01:42.555Z","updated_at":"2025-04-09T10:32:34.990Z","avatar_url":"https://github.com/danielroe.png","language":"TypeScript","funding_links":[],"categories":["TypeScript","Plugins"],"sub_categories":["Templates"],"readme":"# 🚨 Migration to `@nuxt/test-utils` 🚨\n\n`nuxt-vitest` has now been incorporated directly into `@nuxt/test-utils`, which is where development is happening now.\n\n👉 See [release notes](https://github.com/nuxt/test-utils/releases/tag/v3.9.0) and migration guide.\n\n\u003cdetails\u003e\n\u003csummary\u003eOriginal README\u003c/summary\u003e\n\n# nuxt-vitest\n\n[![npm version][npm-version-src]][npm-version-href]\n[![npm downloads][npm-downloads-src]][npm-downloads-href]\n[![Github Actions][github-actions-src]][github-actions-href]\n[![Codecov][codecov-src]][codecov-href]\n\n\u003e A vitest environment for testing code that needs a [Nuxt](https://nuxt.com) runtime environment\n\n- [✨ \u0026nbsp;Changelog](https://github.com/danielroe/nuxt-vitest/blob/main/CHANGELOG.md)\n- [▶️ \u0026nbsp;Playground](https://stackblitz.com/edit/nuxt-vitest)\n\n\u003e **Warning**\n\u003e This library is in active development and you should pin the patch version before using.\n\n## Installation\n\n1. First install `nuxt-vitest`:\n\n```bash\npnpm add -D nuxt-vitest vitest happy-dom\n\n# or\nyarn add --dev nuxt-vitest vitest happy-dom\nnpm i -D nuxt-vitest vitest happy-dom\n```\n\n2. Add `nuxt-vitest` to your `nuxt.config.js`:\n\n```js\nexport default defineNuxtConfig({\n  // ...\n  modules: [\n    'nuxt-vitest'\n  ]\n})\n```\n\n3. Then create a `vitest.config.ts` with the following content:\n\n```js\nimport { defineVitestConfig } from 'nuxt-vitest/config'\n\nexport default defineVitestConfig({\n  // any custom vitest config you require\n})\n```\n\n4. Setting environment for your tests\n\nBy default, `nuxt-vitest` will not change your default Vitest environment, so you can do fine-grain opt-in and run Nuxt tests together with other unit tests.\n\nWe provided a filename convention that test files contains `.nuxt.`, like `*.nuxt.test.{js,ts}` and `*.nuxt.spec.{js,ts}`, will be run in Nuxt environment automatically.\n\nOr you can add `@vitest-environment nuxt` in your test file as a comment to opt-in per test file.\n\n```js\n// @vitest-environment nuxt\nimport { test } from 'vitest'\n\ntest('my test', () =\u003e {\n  // ... test with Nuxt environment!\n})\n```\n\nFinally, you can set `environment: 'nuxt'`, to enable Nuxt environment for **all tests**.\n\n```js\n// vitest.config.ts\nimport { fileURLToPath } from 'node:url'\nimport { defineVitestConfig } from 'nuxt-vitest/config'\n\nexport default defineVitestConfig({\n  test: {\n    environment: 'nuxt',\n    // you can optionally set nuxt-specific environment options\n    // environmentOptions: {\n    //   nuxt: {\n    //     rootDir: fileURLToPath(new URL('./playground', import.meta.url)),\n    //     overrides: {\n    //       // other nuxt config you want to pass\n    //     }\n    //   }\n    // }\n  }\n})\n```\n\nIf you have set `environment: 'nuxt'` by default, you can then opt-out [of the default environment](https://vitest.dev/guide/environment.html#test-environment) per test file as needed.\n\n```js\n// @vitest-environment node\nimport { test } from 'vitest'\n\ntest('my test', () =\u003e {\n  // ... test without Nuxt environment!\n})\n```\n\n## 👉 Important notes\n\nWhen you run your tests within the Nuxt environment, they will be running in a [`happy-dom`](https://github.com/capricorn86/happy-dom) environment. Before your tests run, a global Nuxt app will be initialised (including, for example, running any plugins or code you've defined in your `app.vue`).\n\nThis means you should take particular care not to mutate the global state in your tests (or, if you have, to reset it afterwards).\n\n## 🎭 Built-in mocks\n\n`nuxt-vitest` provides some built-in mocks for the DOM environment, both for `happy-dom` and `jsdom`.\n\n#### `intersectionObserver`\nDefault `true`, creates a dummy class without any functionality for the IntersectionObserver API\n\n\n#### `indexedDB`\nDefault `false`, uses [`fake-indexeddb`](https://github.com/dumbmatter/fakeIndexedDB) to create a functional mock of the IndexedDB API\n\nThese can be configured in the `environmentOptions` section of your `vitest.config.mjs` file:\n\n```js\nexport default defineVitestConfig({\n  test: {\n    environmentOptions: {\n      nuxt: {\n        mock: {\n          intersectionObserver: true,\n          indexedDb: true,\n        }\n      }\n    }\n  }\n})\n````\n\n## 🛠️ Helpers\n\n`nuxt-vitest` provides a number of helpers to make testing Nuxt apps easier.\n\n### `mountSuspended`\n\n`mountSuspended` allows you to mount any vue component within the Nuxt environment, allowing async setup and access to injections from your Nuxt plugins. For example:\n\n```ts\n// tests/components/SomeComponents.nuxt.spec.ts\nit('can mount some component', async () =\u003e {\n    const component = await mountSuspended(SomeComponent)\n    expect(component.text()).toMatchInlineSnapshot(\n        'This is an auto-imported component'\n    )\n})\n\n// tests/App.nuxt.spec.ts\nit('can also mount an app', async () =\u003e {\n    const component = await mountSuspended(App, { route: '/test' })\n    expect(component.html()).toMatchInlineSnapshot(`\n      \"\u003cdiv\u003eThis is an auto-imported component\u003c/div\u003e\n      \u003cdiv\u003e I am a global component \u003c/div\u003e\n      \u003cdiv\u003e/\u003c/div\u003e\n      \u003ca href=\\\\\"/test\\\\\"\u003e Test link \u003c/a\u003e\"\n    `)\n})\n```\n\n### `renderSuspended`\n\n`renderSuspended` allows you to render any vue component within the Nuxt environment using `@testing-library/vue`, allowing async setup and access to injections from your Nuxt plugins.\n\nThis should be used together with utilities from testing-library, e.g. `screen` and `fireEvent`. Install [@testing-library/vue](https://testing-library.com/docs/vue-testing-library/intro) in your project to use these.\nAdditionally testing-library also relies on testing globals for cleanup. You should turn these on in your [Vitest config](https://vitest.dev/config/#globals).\n\nThe passed in component will be rendered inside a `\u003cdiv id=\"test-wrapper\"\u003e\u003c/div\u003e`.\n\n\nExamples:\n\n```ts\n// tests/components/SomeComponents.nuxt.spec.ts\nimport { renderSuspended } from 'nuxt-vitest/utils'\nimport { screen } from '@testing-library/vue'\n\nit('can render some component', async () =\u003e {\n    await renderSuspended(SomeComponent)\n    expect(screen.getByText('This is an auto-imported component')).toBeDefined()\n})\n\n// tests/App.nuxt.spec.ts\nimport { renderSuspended } from 'nuxt-vitest/utils'\n\nit('can also render an app', async () =\u003e {\n    const html = await renderSuspended(App, { route: '/test' })\n    expect(html()).toMatchInlineSnapshot(`\n      \"\u003cdiv id=\\\\\"test-wrapper\\\\\"\u003e\n        \u003cdiv\u003eThis is an auto-imported component\u003c/div\u003e\n        \u003cdiv\u003e I am a global component \u003c/div\u003e\n        \u003cdiv\u003eIndex page\u003c/div\u003e\u003ca href=\\\\\"/test\\\\\"\u003e Test link \u003c/a\u003e\n      \u003c/div\u003e\"\n    `)\n})\n```\n\n### `mockNuxtImport`\n\n`mockNuxtImport` allows you to mock Nuxt's auto import functionality. For example, to mock `useStorage`, you can do so like this:\n\n```ts\nimport { mockNuxtImport } from 'nuxt-vitest/utils'\n\nmockNuxtImport('useStorage', () =\u003e {\n  return () =\u003e {\n    return { value: 'mocked storage' }\n  }\n})\n\n// your tests here\n```\n\n\u003e **Note**: `mockNuxtImport` can only be used once per mocked import per test file. It is actually a macro that gets transformed to `vi.mock` and `vi.mock` is hoisted, as described [here](https://vitest.dev/api/vi.html#vi-mock).\n\nIf you need to mock a Nuxt import and provide different implementations between tests, you can do it by creating and exposing your mocks using [`vi.hoisted`](https://vitest.dev/api/vi.html#vi-hoisted), and then use those mocks in `mockNuxtImport`. You then have access to the mocked imports, and can change the implementation between tests. Be careful to [restore mocks](https://vitest.dev/api/mock.html#mockrestore) before or after each test to undo mock state changes between runs.\n\n\n```ts\nimport { vi } from 'vitest'\nimport { mockNuxtImport } from 'nuxt-vitest/utils'\n\nconst { useStorageMock } = vi.hoisted(() =\u003e {\n  return {\n    useStorageMock: vi.fn().mockImplementation(() =\u003e {\n      return { value: 'mocked storage'}\n    })\n  }\n})\n\nmockNuxtImport('useStorage', () =\u003e {\n  return useStorageMock\n})\n\n// Then, inside a test\nuseStorageMock.mockImplementation(() =\u003e {\n  return { value: 'something else' }\n}) \n```\n\n### `mockComponent`\n\n`mockComponent` allows you to mock Nuxt's component.\nThe first argument can be the component name in PascalCase, or the relative path of the component.\nThe second argument is a factory function that returns the mocked component.\n\nFor example, to mock `MyComponent`, you can:\n\n```ts\nimport { mockComponent } from 'nuxt-vitest/utils'\n\nmockComponent('MyComponent', {\n  props: {\n    value: String\n  },\n  setup(props) {\n    // ...\n  }\n})\n\n// relative path or alias also works\nmockComponent('~/components/my-component.vue', async () =\u003e {\n  // or a factory function\n  return {\n    setup(props) {\n      // ...\n    }\n  }\n})\n\n// or you can use SFC for redirecting to a mock component\nmockComponent('MyComponent', () =\u003e import('./MockComponent.vue'))\n\n// your tests here\n```\n\n\u003e **Note**: You can't reference to local variables in the factory function since they are hoisted. If you need to access Vue APIs or other variables, you need to import them in your factory function.\n\n```ts\nmockComponent('MyComponent', async () =\u003e {\n  const { ref, h } = await import('vue')\n\n  return {\n    setup(props) {\n      const counter = ref(0)\n      return () =\u003e h('div', null, counter.value)\n    }\n  }\n})\n```\n\n### `registerEndpoint`\n\n`registerEndpoint` allows you create Nitro endpoint that returns mocked data. It can come in handy if you want to test a component that makes requests to API to display some data.\n\nThe first argument is the endpoint name (e.g. `/test/`).\nThe second argument is a factory function that returns the mocked data.\n\nFor example, to mock `/test/` endpoint, you can do:\n\n```ts\nimport { registerEndpoint } from 'nuxt-vitest/utils'\n\nregisterEndpoint(\"/test/\", () =\u003e ({\n  test: \"test-field\"\n}))\n```\n\nBy default, your request will be made using the `GET` method. You may use another method by setting an object as the second argument instead of a function.\n\n```ts\nimport { registerEndpoint } from 'nuxt-vitest/utils'\n\nregisterEndpoint(\"/test/\", {\n  method: \"POST\",\n  handler: () =\u003e ({ test: \"test-field\" })\n})\n```\n\n\u003e **Note**: If your requests in a component go to external API, you can use `baseURL` and then make it empty using Nuxt Enviroment Config (`$test`) so all your requests will go to Nitro server.\n\n### Conflict with @nuxt/test-utils\n\n`nuxt-vitest` and `@nuxt/test-utils` need to run in different testing environments and so can't be used in the same file.\n\nIf you would like to use `@nuxt/test-utils` to conduct end-to-end tests on your Nuxt app, you can split your tests into separate files. You then either specify a test environment per-file with the special `// @vitest-environment nuxt` comment, or name your `nuxt-vitest` files with the `.nuxt.spec.ts` extension.\n\n`app.nuxt.spec.js`\n\n```ts\nimport { mockNuxtImport } from \"nuxt-vitest/utils\";\n\nmockNuxtImport('useStorage', () =\u003e {\n  return () =\u003e {\n    return { value: 'mocked storage' }\n  }\n})\n\n```\n\n`app.e2e.spec.js`\n\n```ts\nimport { setup, $fetch } from '@nuxt/test-utils';\n\nawait setup({\n  setupTimeout: 10000,\n});\n\n// ...\n```\n\n## 💻 Development\n\n- Clone this repository\n- Enable [Corepack](https://github.com/nodejs/corepack) using `corepack enable` (use `npm i -g corepack` for Node.js \u003c 16.10)\n- Install dependencies using `pnpm install`\n- Stub the library using `pnpm dev:prepare`\n- Run interactive tests using `pnpm test`\n\n\u003c/details\u003e\n\n## License\n\nMade with ❤️\n\nPublished under the [MIT License](./LICENCE).\n\n\u003c!-- Badges --\u003e\n\n[npm-version-src]: https://img.shields.io/npm/v/nuxt-vitest?style=flat-square\n[npm-version-href]: https://npmjs.com/package/nuxt-vitest\n[npm-downloads-src]: https://img.shields.io/npm/dm/nuxt-vitest?style=flat-square\n[npm-downloads-href]: https://npmjs.com/package/nuxt-vitest\n[github-actions-src]: https://img.shields.io/github/actions/workflow/status/danielroe/nuxt-vitest/ci.yml?branch=main\u0026style=flat-square\n[github-actions-href]: https://github.com/danielroe/nuxt-vitest/actions?query=workflow%3Aci\n[codecov-src]: https://img.shields.io/codecov/c/gh/danielroe/nuxt-vitest/main?style=flat-square\n[codecov-href]: https://codecov.io/gh/danielroe/nuxt-vitest\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanielroe%2Fnuxt-vitest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdanielroe%2Fnuxt-vitest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanielroe%2Fnuxt-vitest/lists"}