Vuetify: [Feature Request] Avoid importing globally Vuetify in all tests

Created on 27 Aug 2018  路  19Comments  路  Source: vuetifyjs/vuetify

Versions and Environment

Vuetify: ^1.1.11
Vue: 2.5.16
Browsers: all
OS: all

Previously worked in:

Vuetify: ^1.1.10
Vue: 2.5.16

Steps to reproduce


Since Vuetify version 1.1.11, developers have to import globally Vuetify in all tests to avoid having 2 multiples Vue instances running (and see a warning referring to #4068 )

localVue.use(Vuetify)

has been replaced by

Vue.use(Vuetify)

Expected Behavior


Using localVue is better because it prevents polluting the original Vue copy during tests.
I expect Vuetify not to use its own instance of Vue.
So I can come back using only localVue.use(Vuetify) in all of my tests

Actual Behavior


I had to use Vue.use(Vuetify) in each of my test files

Reproduction Link

https://codesandbox.io/s/mz86zx5vnj

Watch the warnings generated by the test

Additional Comments:

documentation testing

Most helpful comment

This is super confusing, guys.
Any updates here?

All 19 comments

We need to put together some testing documentation so that this is more clear.

Related to the same issue. When switching from

localVue.use(Vuetify)

to

Vue.use(Vuetify)

I have an issue when any watcher is triggered in my tests. A range Maximum callstack exceeded is triggered and the test fails. Has anyone else experienced this?

Also, should I open a separate issue for this? I can make a reproduction link if needed.

Please create a separate issue @AtofStryker

Actually looks like my issue is related to https://github.com/vuejs/vue-test-utils/issues/647 for any who are interested. Will wait @johnleider for more testing documentation

I expect Vuetify not to use its own instance of Vue

We can't, see https://github.com/vuejs/vue/issues/8278. It might be possible to hack something together with require.cache, but I haven't tried.

Vuetify 1.5.0
Vue 2.6.2

It is still an issue

This is super confusing, guys.
Any updates here?

Same here, I can't find a way to test my project correctly. @johnleider Do we have a documentation somewhere that can give us some exemples to test our projects properly?

Any idea if this will be addressed? And, if so, when? It's kind of a big deal to those of us who take testing seriously.

Thanks in advance for any feedback. And, more than that, thanks for giving us such a remarkable, feature-rich material implementation!

I found the reason of the error.

When you create a _local_ Vue with function createLocalVue you create a VueComponent.
On the startup of Vuetify there is an if where it validates the Vue loaded (internally) with the Vue passed from the installation; here the source

if (OurVue !== Vue) {
      consoleError('Multiple instances of Vue detected\nSee https://github.com/vuetifyjs/vuetify/issues/4068\n\nIf you\'re seeing "$attrs is readonly", it\'s caused by this')
}

Whit debug I saw this (pseudocode):

if ([Function: Vue] !== [Function: VueComponent])

See also #4068

I do have a solution. (but it depends on what you are going to test)

import { shallowMount, createLocalVue } from "@vue/test-utils";
import VueRouter from "vue-router";

import web from "@/views/layouts/web/index.vue";
import sidebar from "@/views/layouts/web/components/SSidebar.vue";
import navbar from "@/views/layouts/web/components/SNavbar.vue";

describe("layouts/web/index.vue", () => {
  let wrapper;
  let localVue;
  beforeAll(() => {
    localVue = createLocalVue();
    localVue.use(VueRouter, {});
    wrapper = shallowMount(web, {
      localVue,
      stubs: {
        VApp: "<div></div>"
      }
    });
  });

  it("Renders Sidebar", () => {
    expect(wrapper.exists(sidebar)).toBe(true);
  });

  it("Renders Navbar", () => {
    expect(wrapper.exists(navbar)).toBe(true);
  });
});

what I just did was not to import Vuetify. instead, I stub <v-app>

stubs: {
   VApp: "<div></div>"
}

P.S. it depends on what you are going to test, I was only testing my methods, props and computed property.

Having same issue in rails
vue 2.6.7
vuetify 1.5.14

[Vuetify] Multiple instances of Vue detected

How do I test a component currently if I use vuetify in almost every one of them? Do I have to shadowMount it in every test with 'localVue.use(vuetify)' when wanting to pass custom properties? That doesn't sound so good.

An update on this issue. Currently with how we must extend the Vue object in order to have proper typescript support, you will have to bootstrap Vue in your test setup file:

// tests/setup.js

import Vue from 'vue'
import Vuetify from 'vuetify'

Vue.use(Vuetify)

I have dropped the ball on providing clear documentation on how to do this and for that I apologize. This is something that I will be adding to the documentation in the coming weeks for the next version.

In regards to a long term solution, I'm accepting any and all suggestions on how to accommodate typescript support while also enabling the bootstrapping of localVue.

Any progress on this?

Thanks @johnleider it worked fine 馃憤

An update on this issue. Currently with how we must extend the Vue object in order to have proper typescript support, you will have to bootstrap Vue in your test setup file:

// tests/setup.js

import Vue from 'vue'
import Vuetify from 'vuetify'

Vue.use(Vuetify)

I have dropped the ball on providing clear documentation on how to do this and for that I apologize. This is something that I will be adding to the documentation in the coming weeks for the next version.

In regards to a long term solution, I'm accepting any and all suggestions on how to accommodate typescript support while also enabling the bootstrapping of localVue.

A great "thank you" from my side too - @johnleider , it works for me too :) Any progress on delivering a solution in the new version?

This will be resolved as of our v3 upgrade to Vue3.

For Vue 2, you can put this code in the jest setup file:

[Vuetify] Multiple instances of Vue detected

// Add a decorator to the console.error function, to suppress displaying error messages that are useless.
const consoleErrorDecorator = function(func) {
const decorator = function(args) {
if (arguments.length === 1 && arguments[0] === "[Vuetify] Multiple instances of Vue detected\n" +
"See https://github.com/vuetifyjs/vuetify/issues/4068\n" +
"\n" +
"If you're seeing \"$attrs is readonly\", it's caused by this") {
return;
}
func.apply(console, [args].concat([].slice.call(arguments)));
}
return decorator;
}
console.error = consoleErrorDecorator(console.error);

Was this page helpful?
0 / 5 - 0 ratings

Related issues

milleraa picture milleraa  路  3Comments

smousa picture smousa  路  3Comments

cawa-93 picture cawa-93  路  3Comments

sebastianmacias picture sebastianmacias  路  3Comments

paladin2005 picture paladin2005  路  3Comments