测试Vuetify(Vue.js)-挂载第二次调用会引发错误

时间:2019-11-27 12:56:29

标签: javascript vue.js testing vuetify.js vuejs3

我目前在测试Vue应用程序时出现行为(特别是在包含vuetify时)。我将Jest用作Test Runner,但是在mocha中也遇到了相同的行为。

首先要注意的是,该问题仅发生在@ vue / test-utils的mount上,而不是shallowMount。同样,只有在您两次使用mount时,它才会发生(我想原因是Vue对象的污染,但以后会更多)。

现在,我的组件只不过是基本v-data-table周围的包装器,其属性值绑定到其项,并为复选框(而不是文本)提供了一些自定义位置。

现在是问题所在。首先,这就是我的测试的第一个变体(基本上是vuetify推荐的样子。看看here。由于测试本身并不重要,我只是期望true在这里是真的< / p>

import Vue from 'vue';
import Vuetify from 'vuetify';
import { mount, createLocalVue, shallowMount } from '@vue/test-utils';

import  PermissionTable from '@/components/PermissionTable.vue';
import { expect } from 'chai';

const localVue = createLocalVue();

// Vue.use is not in the example but leaving it will cause the error that 
// the data table is not registered
Vue.use(Vuetify);

describe('Permissiontable.vue', () => {
  let vuetify;
  let tableItems;

  beforeEach(() => {
    tableItems = [];
    vuetify = new Vuetify();
  });


  it('will test the first thing',() => {
    const wrapper = mount(PermissionTable, {
      localVue,
      vuetify,
      propsData: {
        value: tableItems
      }
    });

    expect(true).to.be(true);
  });


  it('will test the second thing',() => {
    const wrapper = mount(PermissionTable, {
      localVue,
      vuetify,
      propsData: {
        value: tableItems
      }
    });

    expect(true).to.be(true);
  });
});

现在不使用Vue.use(Vuetify)就已经注释了,我将得到以下错误:未注册组件v-data-table。有了它,我就有以下行为

  1. 测试第一件事按预期运行并成功
  2. 第二件事使以下错误失败
  
    

类型错误:无法读取未定义的属性'$ scopedSlots'

  

并且在mount(....)失败。为了使行为更奇怪,如果我调试并停止在这一行, 在调试控制台中手动运行安装,它也会在第一次失败时出现相同的错误。 如果我再次运行它,它将起作用。例如,如果我执行此测试4次,则会发生这种情况。第一将成功->第二将失败->第三和第四将再次成功。

现在,我确定如果函数获得相同的输入,它们的行为也将相同。因此,必须通过第一个调用更改安装的输入。我的猜测是Vue类受到某种方式的污染。因此,如果我看一下localVue的文档,就会发现该实用程序是为了防止污染全局Vue类。所以我将代码更改为

import Vue from 'vue';
import Vuetify from 'vuetify';
import { mount, createLocalVue, shallowMount } from '@vue/test-utils';

import  PermissionTable from '@/components/PermissionTable.vue';
import { expect } from 'chai';

describe('Permissiontable.vue', () => {
  let vuetify;
  let tableItems;
  let localVue;

  beforeEach(() => {
    tableItems = [];
    localVue = createLocalVue();
    vuetify = new Vuetify();
    localVue.use(vuetify);
  });


  it('will test the first thing',() => {
    const wrapper = mount(PermissionTable, {
      localVue,
      vuetify,
      propsData: {
        value: tableItems
      }
    });

    expect(true).to.be(true);
  });


  it('will test the second thing',() => {
    const wrapper = mount(PermissionTable, {
      localVue,
      vuetify,
      propsData: {
        value: tableItems
      }
    });

    expect(true).to.be(true);
  });
});

因此,我创建了一个localVue的新实例,并为每个测试创建了vuetify。并让localVue使用vuetify。现在,这使我回到了错误

  
    

[Vue警告]:未知的自定义元素:-您是否正确注册了组件?对于递归组件,请确保提供“名称”选项。

  

我还尝试了注入vuetify(实例化)或Vuetify的各种更改。使用全局Vue.use等。最后,我总是只剩下这两种行为之一。

现在,工作量似乎是将每个测试写在一个有效的文件中,但我认为这确实是一种不好的做法,我想了解这里到底发生了什么。

我现在还为Vuetify和Vue-Test-Utils创建了Issues,因为我无法想象这是预期的行为,并通过测试作为回购来制作精简的组件版本

rm-test-mount-fails-on-second-exec

要复制:

  1. 克隆存储库
  2. npm安装
  3. npm run test:unit

版本:

Vue: 2.6.10
Vue-Test-Utils :1.0.0-beta.29
验证: 2.1.12

2 个答案:

答案 0 :(得分:0)

在您的第一段代码中唯一看起来不合适的是,您正在编写Vue.use(Vuetify),并且在进行装载时也使用了Vuetify的实例。

我建议您保留Vue.use(Vuetify)并像这样安装组件:

const wrapper = mount(PermissionTable, {
   localVue,   // vuetify is removed from this object
   propsData: {
     value: tableItems
   }
});

另一方面,单元测试通常应使用shallowMount。我不知道您的用例,但请尽可能使用它代替mount

答案 1 :(得分:0)

坏消息

事实证明,这确实是vue-test-utils中的错误。打开问题后,我发现了另一个问题 与我的相似,我很确定其根本原因与我的情况相同。 显然,这是由于 v.beta.29

中的vue utils中发生了更改

可以在这里#1130

找到问题

好消息

有一个解决方法,可以让您的测试再次运行,直到解决该错误为止。您需要使用 sync:false 选项进行挂载,因此在顶部示例中的挂载看起来像

$( "#button" ).click(function() {
  var x = $('#select1').val();
  var y =  $('#select2').val();
  window.location.href = 'https://www.' + x + '.com?trackingid=' + y;
});

我仍然认为这是一个严重的错误,因为无论设置如何,每次运行相同的测试时,它们的行为都应相同。有消息解决后,我将立即更新此帖子。

相关问题