# Test Helpers

All helpers are imported from `@nuxt/test-utils/runtime`.

## `mountSuspended`

Mounts any Vue component within the Nuxt environment, allowing async setup and access to plugin injections. Wraps `@vue/test-utils` `mount` under the hood.

```ts
import { mountSuspended } from '@nuxt/test-utils/runtime'
import { SomeComponent } from '#components'

it('can mount some component', async () => {
  const component = await mountSuspended(SomeComponent)
  expect(component.text()).toMatchInlineSnapshot('"This is an auto-imported component"')
})
```

Mount with a route:

```ts
import { mountSuspended } from '@nuxt/test-utils/runtime'
import App from '~/app.vue'

it('can 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>"
  `)
})
```

**Options:** Accepts all `@vue/test-utils` mount options plus:
- `route`: initial route string, or `false` to skip initial route change (default: `/`)

## `renderSuspended`

Renders a component using `@testing-library/vue` within the Nuxt environment. Requires `@testing-library/vue` as a dependency.

```ts
import { renderSuspended } from '@nuxt/test-utils/runtime'
import { SomeComponent } from '#components'
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()
})
```

The component is rendered inside `<div id="test-wrapper"></div>`.

**Options:** Accepts all `@testing-library/vue` render options plus:
- `route`: initial route string, or `false` to skip initial route change (default: `/`)

## `mockNuxtImport`

Mocks Nuxt auto-imported functions. This is a macro that transforms to `vi.mock` (hoisted).

**Can only be used once per mocked import per test file.**

```ts
import { mockNuxtImport } from '@nuxt/test-utils/runtime'

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

### With type safety and original implementation

```ts
import { mockNuxtImport } from '@nuxt/test-utils/runtime'

mockNuxtImport<typeof useState>('useState', (original) => {
  return (...args) => {
    return { ...original('some-key'), value: 'mocked state' }
  }
})

// Or pass the function directly
mockNuxtImport(useState, (original) => {
  return (...args) => {
    return { ...original('some-key'), value: 'mocked state' }
  }
})
```

### Different implementations per test

Use `vi.hoisted` to create mutable mocks:

```ts
import { vi } from 'vitest'
import { mockNuxtImport } from '@nuxt/test-utils/runtime'

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

mockNuxtImport('useState', () => {
  return useStateMock
})

// In a test:
useStateMock.mockImplementation(() => {
  return { value: 'something else' }
})
```

### Alternative: per-test mocking with vi.fn

```ts
import { beforeEach, vi } from 'vitest'
import { mockNuxtImport } from '@nuxt/test-utils/runtime'

mockNuxtImport(useRoute, original => vi.fn(original))

beforeEach(() => {
  vi.resetAllMocks()
})

// In a test:
const useRouteOriginal = vi.mocked(useRoute).getMockImplementation()!
vi.mocked(useRoute).mockImplementation(
  (...args) => ({ ...useRouteOriginal(...args), path: '/mocked' }),
)
```

## `mockComponent`

Mocks a Nuxt component by PascalCase name or relative path.

```ts
import { mockComponent } from '@nuxt/test-utils/runtime'

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

// By path with factory function
mockComponent('~/components/my-component.vue', () => {
  return defineComponent({
    setup(props) {
      // ...
    },
  })
})

// Redirect to a mock SFC
mockComponent('MyComponent', () => import('./MockComponent.vue'))
```

**Note:** Cannot reference local variables in the factory function (hoisted). Import dependencies inside the factory:

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

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

## `registerEndpoint`

Creates a mock Nitro endpoint that returns test data.

```ts
import { registerEndpoint } from '@nuxt/test-utils/runtime'

// Simple GET endpoint
registerEndpoint('/test/', () => ({
  test: 'test-field',
}))

// With specific HTTP method
registerEndpoint('/test/', {
  method: 'POST',
  handler: () => ({ test: 'test-field' }),
})
```

Options object properties:
- `handler`: event handler function
- `method`: (optional) HTTP method to match (e.g., 'GET', 'POST')
- `once`: (optional) if true, handler is removed after first matching request
