Vue.js-具有复杂子项的单元测试组件

时间:2020-02-25 19:25:07

标签: javascript typescript unit-testing vue.js bootstrap-4

让我们假设一个基本的Bootstrap驱动的HTML表单是自定义Vue组件MyForm.vue的一部分

<template>
  <form>
    <div class="form-group">
      <label for="email">Email address</label>
      <input type="email" class="form-control" id="email">
    </div>
    <button type="submit" class="btn btn-primary">Submit</button>
  </form>
</template>

用于测试模板是否成功渲染的单元测试非常简单

describe('MyForm', () => {

  let wrapper;

  beforeEach(...);

  it('Should be rendered', () => {

    let field = wrapper.find('#email');
    expect(field.element.value).toEqual('');
  });
});

此行有效field.element.value之所以有效,是因为field.element是具有HtmlInputElement属性的本机类型value

如果我想访问复杂组件的属性,例如Bootstrap-Vue的默认输入元素b-form-input,该怎么办? b-form-input类型为BFormInput的处理方式?只需将HtmlElement投射到BFormInput

<template>
  <b-form>
    <b-form-group label="Email">
      <b-form-input type="email" id="email"></b-form-input>
    </b-form-group>
    <b-button type="submit" variant="primary">Submit</button>
  </b-form>
</template>

如何测试非本地组件?特别是类型安全意味着TypeScript。有什么想法吗?

编辑03/01/2020

在我找到muka.gergely条文章之后,对this的回答进行了跟踪。 shallowMount默认情况下对所有子组件都存根,这也阻止了事件处理。此外,shallowMount允许手动取消组件,在我的情况下,取消对b-formb-button的分支以提交事件测试。

const stubs = { // Originally intended to provide custom stubs, here used to unstub components
  BButton,
  BForm,
};

wrapper = shallowMount<MyComponent>(MyComponent, {stubs});

这将导致这些组件被呈现而不是被存根。其余所有组件,例如b-form-input仍会自动存根。

1 个答案:

答案 0 :(得分:2)

在测试元素之前,您必须先mount个元素。您无需测试编写的 Vue 组件,但要测试渲染的输出。

您应该添加 vue-test-utils ,然后再使用单元测试库(很好地支持 Jest Mocha )。

这是 App.vue (带有 Vuetify vue-router )的基本单元测试:

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

Vue.use(Vuetify)

const localVue = createLocalVue()
localVue.use(VueRouter)
const router = new VueRouter()

describe('App.vue', () => {
    let vuetify

    beforeEach(() => {
        vuetify = new Vuetify()
    })

    it('mounts and renders', () => {
        const wrapper = shallowMount(App, { localVue, vuetify, router });

        expect(wrapper.html()).toBeTruthy();
    });
});

您会看到我使用shallowMount()是因为我对测试 App.vue 的子级不感兴趣(它们都有各自的单元测试)。如果曾经,那么我应该改用mount()