Giter Club home page Giter Club logo

nuxt-vitest's Introduction

๐Ÿšจ Migration to @nuxt/test-utils ๐Ÿšจ

nuxt-vitest has now been incorporated directly into @nuxt/test-utils, which is where development is happening now.

๐Ÿ‘‰ See release notes and migration guide.

Original README

nuxt-vitest

npm version npm downloads Github Actions Codecov

A vitest environment for testing code that needs a Nuxt runtime environment

Warning This library is in active development and you should pin the patch version before using.

Installation

  1. First install nuxt-vitest:
pnpm add -D nuxt-vitest vitest happy-dom

# or
yarn add --dev nuxt-vitest vitest happy-dom
npm i -D nuxt-vitest vitest happy-dom
  1. Add nuxt-vitest to your nuxt.config.js:
export default defineNuxtConfig({
  // ...
  modules: [
    'nuxt-vitest'
  ]
})
  1. Then create a vitest.config.ts with the following content:
import { defineVitestConfig } from 'nuxt-vitest/config'

export default defineVitestConfig({
  // any custom vitest config you require
})
  1. Setting environment for your tests

By 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.

We 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.

Or you can add @vitest-environment nuxt in your test file as a comment to opt-in per test file.

// @vitest-environment nuxt
import { test } from 'vitest'

test('my test', () => {
  // ... test with Nuxt environment!
})

Finally, you can set environment: 'nuxt', to enable Nuxt environment for all tests.

// vitest.config.ts
import { fileURLToPath } from 'node:url'
import { defineVitestConfig } from 'nuxt-vitest/config'

export default defineVitestConfig({
  test: {
    environment: 'nuxt',
    // you can optionally set nuxt-specific environment options
    // environmentOptions: {
    //   nuxt: {
    //     rootDir: fileURLToPath(new URL('./playground', import.meta.url)),
    //     overrides: {
    //       // other nuxt config you want to pass
    //     }
    //   }
    // }
  }
})

If you have set environment: 'nuxt' by default, you can then opt-out of the default environment per test file as needed.

// @vitest-environment node
import { test } from 'vitest'

test('my test', () => {
  // ... test without Nuxt environment!
})

๐Ÿ‘‰ Important notes

When you run your tests within the Nuxt environment, they will be running in a 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).

This means you should take particular care not to mutate the global state in your tests (or, if you have, to reset it afterwards).

๐ŸŽญ Built-in mocks

nuxt-vitest provides some built-in mocks for the DOM environment, both for happy-dom and jsdom.

intersectionObserver

Default true, creates a dummy class without any functionality for the IntersectionObserver API

indexedDB

Default false, uses fake-indexeddb to create a functional mock of the IndexedDB API

These can be configured in the environmentOptions section of your vitest.config.mjs file:

export default defineVitestConfig({
  test: {
    environmentOptions: {
      nuxt: {
        mock: {
          intersectionObserver: true,
          indexedDb: true,
        }
      }
    }
  }
})

๐Ÿ› ๏ธ Helpers

nuxt-vitest provides a number of helpers to make testing Nuxt apps easier.

mountSuspended

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:

// tests/components/SomeComponents.nuxt.spec.ts
it('can mount some component', async () => {
    const component = await mountSuspended(SomeComponent)
    expect(component.text()).toMatchInlineSnapshot(
        'This is an auto-imported component'
    )
})

// tests/App.nuxt.spec.ts
it('can also mount an app', async () => {
    const component = await mountSuspended(App, { route: '/test' })
    expect(component.html()).toMatchInlineSnapshot(`
      "<div>This is an auto-imported component</div>
      <div> I am a global component </div>
      <div>/</div>
      <a href=\\"/test\\"> Test link </a>"
    `)
})

renderSuspended

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.

This should be used together with utilities from testing-library, e.g. screen and fireEvent. Install @testing-library/vue in your project to use these. Additionally testing-library also relies on testing globals for cleanup. You should turn these on in your Vitest config.

The passed in component will be rendered inside a <div id="test-wrapper"></div>.

Examples:

// tests/components/SomeComponents.nuxt.spec.ts
import { renderSuspended } from 'nuxt-vitest/utils'
import { screen } from '@testing-library/vue'

it('can render some component', async () => {
    await renderSuspended(SomeComponent)
    expect(screen.getByText('This is an auto-imported component')).toBeDefined()
})

// tests/App.nuxt.spec.ts
import { renderSuspended } from 'nuxt-vitest/utils'

it('can also render an app', async () => {
    const html = await renderSuspended(App, { route: '/test' })
    expect(html()).toMatchInlineSnapshot(`
      "<div id=\\"test-wrapper\\">
        <div>This is an auto-imported component</div>
        <div> I am a global component </div>
        <div>Index page</div><a href=\\"/test\\"> Test link </a>
      </div>"
    `)
})

mockNuxtImport

mockNuxtImport allows you to mock Nuxt's auto import functionality. For example, to mock useStorage, you can do so like this:

import { mockNuxtImport } from 'nuxt-vitest/utils'

mockNuxtImport('useStorage', () => {
  return () => {
    return { value: 'mocked storage' }
  }
})

// your tests here

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.

If 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, 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 before or after each test to undo mock state changes between runs.

import { vi } from 'vitest'
import { mockNuxtImport } from 'nuxt-vitest/utils'

const { useStorageMock } = vi.hoisted(() => {
  return {
    useStorageMock: vi.fn().mockImplementation(() => {
      return { value: 'mocked storage'}
    })
  }
})

mockNuxtImport('useStorage', () => {
  return useStorageMock
})

// Then, inside a test
useStorageMock.mockImplementation(() => {
  return { value: 'something else' }
}) 

mockComponent

mockComponent allows you to mock Nuxt's component. The first argument can be the component name in PascalCase, or the relative path of the component. The second argument is a factory function that returns the mocked component.

For example, to mock MyComponent, you can:

import { mockComponent } from 'nuxt-vitest/utils'

mockComponent('MyComponent', {
  props: {
    value: String
  },
  setup(props) {
    // ...
  }
})

// relative path or alias also works
mockComponent('~/components/my-component.vue', async () => {
  // or a factory function
  return {
    setup(props) {
      // ...
    }
  }
})

// or you can use SFC for redirecting to a mock component
mockComponent('MyComponent', () => import('./MockComponent.vue'))

// your tests here

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.

mockComponent('MyComponent', async () => {
  const { ref, h } = await import('vue')

  return {
    setup(props) {
      const counter = ref(0)
      return () => h('div', null, counter.value)
    }
  }
})

registerEndpoint

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.

The first argument is the endpoint name (e.g. /test/). The second argument is a factory function that returns the mocked data.

For example, to mock /test/ endpoint, you can do:

import { registerEndpoint } from 'nuxt-vitest/utils'

registerEndpoint("/test/", () => ({
  test: "test-field"
}))

By 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.

import { registerEndpoint } from 'nuxt-vitest/utils'

registerEndpoint("/test/", {
  method: "POST",
  handler: () => ({ test: "test-field" })
})

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.

Conflict with @nuxt/test-utils

nuxt-vitest and @nuxt/test-utils need to run in different testing environments and so can't be used in the same file.

If 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.

app.nuxt.spec.js

import { mockNuxtImport } from "nuxt-vitest/utils";

mockNuxtImport('useStorage', () => {
  return () => {
    return { value: 'mocked storage' }
  }
})

app.e2e.spec.js

import { setup, $fetch } from '@nuxt/test-utils';

await setup({
  setupTimeout: 10000,
});

// ...

๐Ÿ’ป Development

  • Clone this repository
  • Enable Corepack using corepack enable (use npm i -g corepack for Node.js < 16.10)
  • Install dependencies using pnpm install
  • Stub the library using pnpm dev:prepare
  • Run interactive tests using pnpm test

License

Made with โค๏ธ

Published under the MIT License.

nuxt-vitest's People

Contributors

antfu avatar danielroe avatar devdengchao avatar dsvgl avatar enkot avatar erikkkwu avatar exer7um avatar floriankapaun avatar gangsthub avatar ghazialhouwari avatar huang-julien avatar jgonz3 avatar jrutila avatar lassediercks avatar luzefiru avatar maartenvanhunsel avatar mannil avatar mvanalphen avatar nicolaspayot avatar niko-chaffinchicas avatar odinti avatar olaalsaker avatar oskarols avatar pi0 avatar renovate[bot] avatar rinux55 avatar ryoji-yamauchi-blc avatar timvdeijnden avatar userquin avatar yassilah avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nuxt-vitest's Issues

Maige Usage

Thanks for trying Maige.

Running GPT-based services is pricey. At this point, we ask you to add payment info to continue using Maige.

Add payment info

Feel free to close this issue.

Project status

This module has been moved into @nuxt/test-utils to become officially supported as the unit testing solution using vitest within a runtime Nuxt environment.

You can read more within the test utils roadmap.

๐Ÿ‘‰ Migration

๐Ÿšง Migration guide coming soon once v3.9 of @nuxt/test-utils is released.

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Awaiting Schedule

These updates are awaiting their schedule. Click on a checkbox to get an update now.

  • chore(deps): update devdependency @nuxt/devtools to v1.0.6
  • chore(deps): update devdependency vue-tsc to v1.8.25
  • chore(deps): update all linters (eslint, eslint-config-prettier, prettier)
  • chore(deps): update devdependency lint-staged to v15.2.0
  • chore(deps): update devdependency typescript to v5.3.3
  • chore(deps): update pnpm to v8.12.1
  • chore(deps): lock file maintenance

Rate-Limited

These updates are currently rate-limited. Click on a checkbox below to force their creation now.

  • chore(deps): update dependency @vue/test-utils to v2.4.3
  • chore(deps): update dependency ufo to v1.3.2
  • chore(deps): update dependency h3 to v1.9.0
  • chore(deps): update dependency std-env to v3.6.0
  • chore(deps): update dependency unenv to v1.8.0
  • chore(deps): update github/codeql-action action to v3
  • chore(deps): update test packages (major) (@vitest/coverage-v8, @vitest/ui, jsdom, vitest)
  • ๐Ÿ” Create all rate-limited PRs at once ๐Ÿ”

Edited/Blocked

These updates have been manually edited so Renovate will no longer make changes. To discard all commits and start over, click on a checkbox.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

github-actions
.github/workflows/ci.yml
  • actions/checkout v4
  • actions/setup-node v4
  • actions/checkout v4
  • actions/setup-node v4
  • codecov/codecov-action v3
.github/workflows/codeql.yml
  • actions/checkout v4
  • github/codeql-action v2
  • github/codeql-action v2
  • github/codeql-action v2
npm
package.json
  • @nuxt/eslint-config 0.2.0
  • @nuxt/schema 3.7.4
  • @vitest/coverage-v8 0.33.0
  • changelogen 0.5.5
  • eslint 8.51.0
  • eslint-config-prettier 9.0.0
  • eslint-plugin-prettier 5.0.1
  • husky 8.0.3
  • lint-staged 15.0.2
  • nuxt 3.7.4
  • prettier 3.0.3
  • typescript 5.2.2
  • unbuild 2.0.0
  • vitest 0.33.0
  • vue 3.3.4
  • vue-tsc 1.8.19
  • pnpm 8.7.6
packages/nuxt-vitest/package.json
  • @nuxt/kit ^3.7.4
  • @vitest/ui ^0.33.0
  • defu ^6.1.2
  • get-port-please ^3.1.1
  • perfect-debounce ^1.0.0
  • std-env ^3.4.3
  • @nuxt/module-builder 0.5.2
  • @nuxt/schema 3.7.4
  • nuxt 3.7.4
  • vitest 0.33.0
  • @vitejs/plugin-vue *
  • @vitejs/plugin-vue-jsx *
  • vite *
  • vitest ^0.24.5 || ^0.26.0 || ^0.27.0 || ^0.28.0 || ^0.29.0 || ^0.30.0 || ^0.33.0
packages/vitest-environment-nuxt/package.json
  • @nuxt/kit ^3.7.4
  • @vue/test-utils ^2.4.1
  • defu ^6.1.2
  • estree-walker ^3.0.3
  • fake-indexeddb ^5.0.0
  • h3 ^1.8.1
  • local-pkg ^0.5.0
  • magic-string ^0.30.3
  • ofetch ^1.3.3
  • radix3 ^1.1.0
  • ufo ^1.3.0
  • unenv ^1.7.4
  • @testing-library/vue 8.0.1
  • @types/jsdom 21.1.6
  • happy-dom 12.1.6
  • jsdom 22.1.0
  • rollup 3.29.4
  • vue 3.3.4
  • @testing-library/vue 8.0.1
  • happy-dom ^9.10.9 || ^10.0.0 || ^11.0.0 || ^12.0.0
  • jsdom ^22.0.0
  • vitest ^0.24.5 || ^0.26.0 || ^0.27.0 || ^0.28.0 || ^0.29.0 || ^0.30.0 || ^0.33.0
  • vue ^3.2.45
  • vue-router ^4.0.0
playground/package.json
  • idb-keyval ^6.2.1
  • @nuxt/devtools 1.0.5
  • @testing-library/vue 8.0.1
  • happy-dom 12.1.2
  • jsdom 22.1.0
  • nuxt 3.7.4
  • nuxt-vitest 0.11.5
  • typescript 5.2.2
  • vitest 0.33.0
  • vitest-environment-nuxt 0.11.5
  • vue-tsc 1.8.19

  • Check this box to trigger a request for Renovate to run again on this repository

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.