• This repository has been archived on 19/Dec/2023
  • Stars
    star
    369
  • Rank 115,266 (Top 3 %)
  • Language
    TypeScript
  • License
    MIT License
  • Created almost 2 years ago
  • Updated 10 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

An vitest environment with support for testing code that needs a Nuxt runtime environment

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

# or
yarn add --dev nuxt-vitest
npm i -D nuxt-vitest
  1. Add nuxt-vitest to your nuxt.config.js:
export default defineNuxtConfig({
  // ...
  modules: [
    'nuxt-vitest'
  ]
})
  1. Then create a vitest.config.mjs 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 be take particular care not to mutate the global state in your tests (or, if you have, to reset it afterwards).

🛠️ Helpers

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

mountSuspended

// TODO:

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 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 using a global variable as the returned value of your mock function and change its implementation within each test. Be careful to restore mocks before or after each test to undo mock state changes between runs.

// useStorageMock.ts
let useStorageMock = vi.fn(() => {
  return { value: 'mocked storage' }
})
export default useStorageMock
import useStorageMock from './useStorageMock'
import { mockNuxtImport } from 'nuxt-vitest/utils'

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"
})

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.

More Repositories

1

typed-vuex

🏦 A typed store accessor for vanilla Vuex.
TypeScript
346
star
2

page-speed.dev

Vue
320
star
3

nuxt-zero-js

Remove all client-side JS from your Nuxt 3 app
TypeScript
191
star
4

nuxt-workers

SSR-safe, zero-config Web Workers integration for Nuxt.
TypeScript
186
star
5

unplugin-purge-polyfills

A tiny plugin to replace package imports with better native code.
TypeScript
184
star
6

sanity-typed-queries

A typed, zero-dependency schema generator and query builder for Sanity.
TypeScript
173
star
7

nuxt-time

⏰ SSR-safe time element for Nuxt 3
TypeScript
159
star
8

siroc

Zero-config build tooling for Node
TypeScript
149
star
9

vue-bind-once

A tiny, SSR-safe directive for binding random data to an element.
TypeScript
120
star
10

nuxt-full-static

Full static implementation for Nuxt 3
TypeScript
117
star
11

roe.dev

This is the code and content for my personal website, built in Nuxt.
TypeScript
113
star
12

n3rdle

Vue
90
star
13

goff

Sync GitHub issues offline into a local folder
TypeScript
70
star
14

rollup-plugin-pure

Annotate functions as pure for Rollup
TypeScript
63
star
15

nuxt-capo

`capo.js` implementation for Nuxt 3
TypeScript
59
star
16

vue-sanity

Sanity integration for Vue Composition API
TypeScript
55
star
17

nuxt-vercel-isr

A tiny demo to show off Nuxt's route rules integration with Vercel.
Vue
55
star
18

nuxt-web-bundle

Generate web bundles with Nuxt
TypeScript
51
star
19

nuxt-pre-hydrate

TypeScript
46
star
20

spooon

This is a tiny recipe app built in Nuxt for a live-coding session at Vue.js Nation 2024.
Vue
33
star
21

nuxt-timings-module

TypeScript
32
star
22

n3dium

This is a tiny, incomplete example for a paywalled content site built in Nuxt 3 for a live-coding session at Vue.js Global Summit 2022.
Vue
30
star
23

trellis-valet-driver

A driver for Laravel Valet that supports the default Trellis install.
PHP
26
star
24

postcss-capsize

TypeScript
25
star
25

agent-conf-2023

A demo of integrating React, Vite and Nitro for AgentConf 2023.
JavaScript
25
star
26

nuxt-vue3-module

TypeScript
22
star
27

nuxt-vscode-template

TypeScript
20
star
28

nuxt-deno

TypeScript
18
star
29

stream-vue

Vue component for Cloudflare Stream.
TypeScript
16
star
30

jetbrains-2023

Vue
15
star
31

firstcommit.is

TypeScript
14
star
32

nuxt-hanko

TypeScript
12
star
33

frontend-nation-2024

Tiny Nuxt multiplayer app built for a live-coding session at Frontend Nation 2024.
TypeScript
11
star
34

iodigital-2024

Vue
11
star
35

vuejslive

A demo of integrating Vue, Vite and Nitro for Vue.js Live London 2023.
JavaScript
10
star
36

domain-sync

A tiny script that migrates all my Gandi domains to use Cloudflare DNS.
TypeScript
10
star
37

nuxt-turnstile

Cloudflare Turnstile integration for Nuxt
TypeScript
9
star
38

template

JavaScript
9
star
39

future-of-coding-2024

Vue
9
star
40

vuejs-de

TypeScript
7
star
41

unmeta

Simple tools for interacting with HTML metadata tags
TypeScript
7
star
42

vercel-kv

TypeScript
7
star
43

botornot

Vue
7
star
44

nuxt-emoji-blast

TypeScript
6
star
45

renovate

5
star
46

native-esm

JavaScript
4
star
47

nuxt-typed-vuex-example

Vue
4
star
48

vuejs-athens-2024

Vue
4
star
49

flowers

Vue
4
star
50

_productivity_app

Bicep
4
star
51

wearedevs

JavaScript
3
star
52

nuxt3-typed-routes

Vue
3
star
53

pigeon

Vue
3
star
54

danielroe

3
star
55

nuxt-nightly-action

TypeScript
3
star
56

gdg-portlaoise-2024

Vue
3
star
57

vue-subpath-conditions

TypeScript
3
star
58

nuxt-font-metrics

Font metric overrides to reduce CLS
TypeScript
2
star
59

nuxt-demo

TypeScript
2
star
60

partytown-example

TypeScript
2
star
61

viteconf

TypeScript
2
star
62

nuxt3-repros

TypeScript
2
star
63

vue3-pre-window-repro

JavaScript
2
star
64

digital-labin

JavaScript
2
star
65

nuxt-typed-vuex-vue-example

Vue
2
star
66

netlify-dynamic-builder

TypeScript
2
star
67

openflights-loader

TypeScript
1
star
68

building-better-with-nuxt-3

TypeScript
1
star
69

vuejs-berlin

Vue
1
star
70

.github

1
star
71

nuxt-fonts-demo

TypeScript
1
star
72

building-a-pwa-with-nuxt

JavaScript
1
star
73

sanity-module

1
star
74

critters-test

Vue
1
star
75

nuxi-upgrade-yarn3

TypeScript
1
star
76

nuxt-edge-preset

Vue
1
star
77

formkit-init

TypeScript
1
star
78

axios-types

Vue
1
star
79

nuxt-typed-vuex-ts-example

Vue
1
star
80

css-flash-repro

Vue
1
star