Search code examples
vuejs2vue-routerjestjsvue-test-utils

Snapshot Testing with Vue-Router


I'm trying to run jest-snapshot tests in a Vue app created using the Vue-cli app. When I test a component that have a router-link in it, I receive the following warning.

 [Vue warn]: Unknown custom element: <router-link> - did you register 
 the component correctly? For recursive components, make sure to 
 provide the "name" option.

Following the documentation here Unit tests with View Router I can stub out the router-link, but that doesn't pass my snapshot test. Has anyone run into this issue before?


Solution

  • Updated: A more consistent solution

    tl;dr:

    The solution I found that works consistently is to create a localVue (usually outside the scope of the describe() blocks) and add the RoutherLinkStub as a component.

    import { mount, RouterLinkStub, createLocalVue } from '@vue/test-utils';
    
    const localVue = createLocalVue();
    localVue.component('router-link', RouterLinkStub);
    
    const wrapper = mount(Component, { localVue });
    

    The documentation doesn't make the solution obvious because it seems to be something of a hybrid of the page you linked to and this one about RouterLinkStub.

    From that page:

    import { mount, RouterLinkStub } from '@vue/test-utils'
    
    const wrapper = mount(Component, {
      stubs: {
        RouterLink: RouterLinkStub
      }
    })
    

    That solution works in most cases. If you have a case where you need to use mount and your router-link is a not in the component being tested but the one below it, you will still get that warning. Now, if you are in that situation, it's worth reflecting if you're writing your test properly (are you testing too much rather than a small unit?), but I have a situation or two where if I shallow instead of mount, the snapshot test is worthless because it renders children as <!----> when I callexpect(wrapper.html()).toMatchSnapshot()`.

    A Note on Snapshot Tests: I haven't actually seen examples of people using the Wrapper.html() method for snapshot testing, but it really seems like the best solution in my experimenting. vue-server-renderer is a long walk for what appears to be the same result. Accessing the vm property of Wrapper gives you access to the $el property, without much trouble, but it's just a more whitespace-heavy rendering of html().