question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

VTL for Vue 3: The routes option does not work correctly

See original GitHub issue

Describe the bug When using the routes option of the render function, it throws up some warnings that have to do with the _history property and the asynchronic handling that vue router 4 has. This causes you to not be able to use the routes option correctly.

To Reproduce

import { render, screen } from '@testing-library/vue'
import '@testing-library/jest-dom'
import { defineComponent } from 'vue'
import { RouteRecordRaw } from 'vue-router'

test('Component with route', () => {
  const ComponentA = defineComponent({
    name: 'ComponentA',
    props: {
      to: {
        type: Object,
        required: true
      }
    },
    template: `<router-link :to="to" role="button">Learn More</router-link>`
  })

  const ComponentB = defineComponent({
    name: 'ComponentB'
  })

  const routeRecordRaw: RouteRecordRaw = {
    path: '/',
    name: 'componentB',
    component: ComponentB
  }

  const to = { name: routeRecordRaw.name }

  render(ComponentA, {
    props: { to },
    routes: [routeRecordRaw]
  })

  const button = screen.getByRole('button')

  expect(button).toBeInTheDocument()
  expect(button?.getAttribute('href')).toBe(routeRecordRaw.path)
})

This throws the following warning

console.warn node_modules/vue-router/dist/vue-router.cjs.js:75
    [Vue Router warn]: Unexpected error when starting the router: TypeError: Cannot read property '_history' of null

The warning is known. This is explained in the vue-test-utils v2 documentation https://vue-test-utils.vuejs.org/v2/guide/vue-router.html#with-a-real-router

So to solve it apply what is indicated in documentation

import { render, screen } from '@testing-library/vue'
import '@testing-library/jest-dom'
import { defineComponent } from 'vue'
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'

test('Component with route', async () => {
  const ComponentA = defineComponent({
    name: 'ComponentA',
    props: {
      to: {
        type: Object,
        required: true
      }
    },
    template: `<router-link :to="to" role="button">Learn More</router-link>`
  })

  const ComponentB = defineComponent({
    name: 'ComponentB'
  })

  const routeRecordRaw: RouteRecordRaw = {
    path: '/',
    name: 'componentB',
    component: ComponentB
  }

  const router = createRouter({
    history: createWebHistory(process.env.BASE_URL),
    routes: [routeRecordRaw]
  })

  router.push('/')
  await router.isReady()

  const to = { name: routeRecordRaw.name }

  render(ComponentA, {
    props: { to },
    global: {
      plugins: [router]
    }
  })

  const button = screen.getByRole('button')

  expect(button).toBeInTheDocument()
  expect(button?.getAttribute('href')).toBe(routeRecordRaw.path)
})

Expected behavior Be able to correctly use the routes option provided by the render function

Related information:

  • @testing-library/vue version: ^6.3.1
  • Vue version: ^3.0.0
  • node version: 14.4.0
  • npm version: 6.14.9

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:25 (16 by maintainers)

github_iconTop GitHub Comments

1reaction
lmiller1990commented, May 26, 2021

I have definitely seen the _history error before. It was related to awaiting the router to be read, but you’ve already done that.

I wonder if this is a bug here? I feel like it might be either in Test Utils or something else. I wonder if we can reproduce it without Testing Library (VTU + Jest). I wonder if you need to have a top level component (like <app>) with a <router-view /> for this to work as expected.

1reaction
afontcucommented, Jan 19, 2021

Going back to this. As I see it, we’re down to two options:

  1. Make render async when routes is present, and then call router.isReady() internally. API change: you’d need to await render(Comp, { routes }), but not when routes is not there. We could warn users somehow (plus, TS types would help, too).

  2. Remove vuex/router integration for Vue 3, and leave it to users. This would make users responsible for setting up router (and store) and call router.isReady(), which is an implementation detail (even though it is on the Arrange section of tests, which is OK, I guess), and would keep render sync. This solution makes VTL more aligned to other Testing Lib flavors.

To be fair, setting up your own router/vuex isn’t that bad now with VTU 2 since there’s no need to set up a local vue instance. On the other hand, “hiding” the need to mke router ready feels… right for users.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Routing in Vue3: Navigating the Options - CODE Magazine
This is where Vue Routing comes in. It allows you to build the kinds of apps you need to create. Let's see how...
Read more >
Lazily added routes are not accessible by url - Stack Overflow
When component introduces new route for its router-view it is working while going trough the app, but once you refresh or try to...
Read more >
FAQ | Testing Library
Short answer: yes, it is. If you use Vue Testing Library (VTL) there's no need to install @vue/test-utils. Longer answer: VTL is built...
Read more >
Migrating from Vue 2 - Vue Router
This is no longer possible and there are two options: Using the name of the route without the param: redirect: { name: 'events'...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found