testing-library / vue-testing-library

šŸ¦Ž Simple and complete Vue.js testing utilities that encourage good testing practices.
http://testing-library.com/vue
MIT License
1.07k stars 111 forks source link

Docs: Provide an example of useRoute() with vue router 4.x to access route params #252

Closed natemate90 closed 2 years ago

natemate90 commented 2 years ago

I'm trying to mock the vue-router useRoute() function.

Test should pass as I mock useRoute inside vue-router, but instead the test fails:

 FAIL  src/components/base/sidebar/SidebarMenu.spec.ts (9.592 s)
  ā— Console

    console.warn
      [Vue warn]: injection "Symbol([vue-router]: route location)" not found.
        at <Anonymous ref="VTU_COMPONENT" >
        at <VTUROOT>

      22 | import { useRoute } from 'vue-router'
      23 |
    > 24 | const route = useRoute()
         |               ^
      25 |
      26 | const { helplinks, navigation } = useSidebarLinks(route)
      27 | </script>

      at warn (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:6800:17)
      at Object.inject (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:1508:13)
      at Object.useRoute (node_modules/vue-router/dist/vue-router.cjs.js:3406:16)
      at setup (src/components/base/sidebar/SidebarMenu.vue:24:15)
      at callWithErrorHandling (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:6917:22)
      at setupStatefulComponent (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:6535:29)
      at setupComponent (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:6491:11)
      at mountComponent (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:4369:13)

    console.warn
      [Vue warn]: Unhandled error during execution of setup function
        at <Anonymous ref="VTU_COMPONENT" >
        at <VTUROOT>

      at warn (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:6800:17)
      at logError (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:6974:9)
      at handleError (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:6966:5)
      at callWithErrorHandling (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:6920:9)
      at setupStatefulComponent (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:6535:29)
      at setupComponent (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:6491:11)
      at mountComponent (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:4369:13)
      at processComponent (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:4344:17)

Related information:

Relevant code or config (if any)


beforeEach(() => {
  jest.mock('vue-router', () => ({
    useRoute: () => ({
      params: {
        locale: 'en',
        id: '123abc'
      }
    })
  }))
})

Additional context

sand4rt commented 2 years ago

@natemate90 You can find an example here

natemate90 commented 2 years ago

This shows an example of Vue Router with Vue 2. I'm looking for the Vue Router 4.x (with Vue 3)

natemate90 commented 2 years ago

I created a minimal reproduction example for my problem. I have 2 Files 1) ComponentWithUseRoute.vue 2) ComponentWithUseRoute.spec.ts

ComponentWithUseRoute.vue:

<template>
  <div>{{ route.params }}</div>
</template>

<script lang="ts" setup>
import { useRoute } from 'vue-router'
const route = useRoute()
</script>

ComponentWithUseRoute.spec.ts


import { render } from '@testing-library/vue'
import ComponentWithUseRoute from './ComponentWithUseRoute.vue'

beforeEach(() => {
  jest.mock('vue-router', () => ({
    useRoute: jest.fn(() => ({
      name: 'Home',
      params: {
        lang: 'en'
      }
    }))
  }))
})

test('It shows the route params', async () => {
  render(ComponentWithUseRoute)
})

The test fails:


  ā— It shows the route params

    TypeError: Cannot read property 'params' of undefined

      at Proxy.render (src/tests/useRoute/ComponentWithUseRoute.vue:31:105)
      at renderComponentRoot (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:759:44)
      at ReactiveEffect.componentUpdateFn [as fn] (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:4475:57)
      at ReactiveEffect.run (node_modules/@vue/reactivity/dist/reactivity.cjs.js:164:29)
      at setupRenderEffect (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:4600:9)
      at mountComponent (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:4386:9)
      at processComponent (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:4344:17)
      at patch (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:3949:21)
      at ReactiveEffect.componentUpdateFn [as fn] (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:4482:21)
      at ReactiveEffect.run (node_modules/@vue/reactivity/dist/reactivity.cjs.js:164:29)
      at setupRenderEffect (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:4600:9)
      at mountComponent (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:4386:9)
      at processComponent (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:4344:17)
      at patch (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:3949:21)
      at render (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5081:13)
      at mount (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:3467:25)
      at Object.app.mount (node_modules/@vue/runtime-dom/dist/runtime-dom.cjs.js:1495:23)
      at mount (node_modules/@vue/test-utils/dist/vue-test-utils.cjs.js:7833:18)
      at Object.render (node_modules/@testing-library/vue/dist/render.js:45:38)
      at src/tests/useRoute/ComponentWithUseRoute.spec.ts:17:3
      at step (src/tests/useRoute/ComponentWithUseRoute.spec.ts:33:23)
      at Object.next (src/tests/useRoute/ComponentWithUseRoute.spec.ts:14:53)
      at src/tests/useRoute/ComponentWithUseRoute.spec.ts:8:71
      at Object.<anonymous>.__awaiter (src/tests/useRoute/ComponentWithUseRoute.spec.ts:4:12)
      at Object.<anonymous> (src/tests/useRoute/ComponentWithUseRoute.spec.ts:16:35)

  console.warn
    [Vue warn]: injection "Symbol([vue-router]: route location)" not found.
      at <Anonymous ref="VTU_COMPONENT" >
      at <VTUROOT>

      5 | <script lang="ts" setup>
      6 | import { useRoute } from 'vue-router'
    > 7 | const route = useRoute()
        |               ^
      8 | </script>
      9 |

      at warn (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:6800:17)
      at Object.inject (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:1508:13)
      at Object.useRoute (node_modules/vue-router/dist/vue-router.cjs.js:3406:16)
      at setup (src/tests/useRoute/ComponentWithUseRoute.vue:7:15)
      at callWithErrorHandling (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:6917:22)
      at setupStatefulComponent (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:6535:29)
      at setupComponent (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:6491:11)

  console.warn
    [Vue warn]: Unhandled error during execution of render function
      at <Anonymous ref="VTU_COMPONENT" >
      at <VTUROOT>

      at warn (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:6800:17)
      at logError (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:6974:9)
      at handleError (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:6966:5)
      at renderComponentRoot (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:876:9)
      at ReactiveEffect.componentUpdateFn [as fn] (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:4475:57)
      at ReactiveEffect.run (node_modules/@vue/reactivity/dist/reactivity.cjs.js:164:29)
      at setupRenderEffect (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:4600:9)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        7.157 s
Ran all test suites related to changed files.

Watch Usage: Press w to show more.

@afontcu any chance you can create a working example? šŸ™ šŸ˜„

natemate90 commented 2 years ago

Solution: It appeared to be as simple as removing foreach

ComponentWithUseRoute.spec.ts

import { render } from '@testing-library/vue'
import ComponentWithUseRoute from './ComponentWithUseRoute.vue'

jest.mock('vue-router', () => ({
  useRoute: jest.fn(() => ({
    name: 'Home',
    params: {
      lang: 'en'
    }
  }))
}))

test('It shows the route params', async () => {
  render(ComponentWithUseRoute)
})