【问题标题】:Test-utils does not update the DOM after firing triggers in all tests except the first在除第一个测试之外的所有测试中触发触发器后,Test-utils 不会更新 DOM
【发布时间】:2019-12-12 21:16:18
【问题描述】:

我正在尝试在触发 vuelidate 后检查有关在 HTML/DOM 中填写字段的错误消息。在click 触发器之后成功运行。 一切都在测试中起作用:安装、元素搜索、触发器、NextTick、vuelidate - 错误返回。但我无法在触发后的第二个测试(以及describe() 中的所有后续测试)中更新 DOM。第一个测试耐心等待await NextTick(),validator+vuetify给label元素添加class。但每个测试单独工作正常。

请告诉我。为什么我不能在第二个相同的测试中重复相同的代码?谢谢你。 附言我使用 VUE + VUETIFY + JEST。

import { mount } from '@vue/test-utils'
import 'babel-polyfill';
import Vue from "vue";
import Router from 'vue-router';
import store from "~/store";
import types from '~/store/types'
import util from '~/util'
import i18n from '~/i18n'
import Client from '~/service/Client'
import Login from '~/views/Login'
import Vuetify from 'vuetify'
import Snotify from 'vue-snotify'
import storage from '~/storage'
import config from '~/config'
import inflection from 'inflection'
import Vuelidate from 'vuelidate'

Vue.config.productionTip = false;
Vue.prototype.$storage = storage;
Vue.prototype.$config = config;
Vue.prototype.$inflection = inflection;
Vue.use(Vuelidate);
Vue.use(Snotify);
Vue.use(Client);
Vue.use(util);
Vue.use(Vuetify);
Vue.use(Router);

describe("Validate login form", () => {

  const route = {
    path: '/login',
    meta: {
      public: true,
    }
  };

  const r = new Router({
    base: '/',
    mode: 'history', // hash
    linkActiveClass: 'active',
    routes: [route]
  });

  const errors = ['error--text'];

  const factory = (values = {}) => {

    return mount(Login, {
      types,
      r,
      i18n,
      store,
      data () {
        return {
          ...values
        }
      }
    })
  };

  it("first it", async () => {

    const wrapper = factory({ email: "" }); // new instance with data

    wrapper.find(".v-btn--block").trigger("click"); // success firing
    await wrapper.vm.$nextTick();
    expect(wrapper.html()).toMatchSnapshot()

    // expect( wrapper.vm.$v.email.$error ).toBe(true); // ok true

    // DOM updated
    expect ( wrapper.find("label[for='email']").classes() ).toEqual(expect.arrayContaining(errors)); // ok true - classes containing error class

  });

  it("second it", async () => {

    const wrapper = factory({ email: "" }); // new instance with data

    wrapper.find(".v-btn--block").trigger("click"); // success firing
    await wrapper.vm.$nextTick();
    expect(wrapper.html()).toMatchSnapshot();

    // expect( wrapper.vm.$v.email.$error ).toBe(true); // ok true

    // DOM not updated
    expect ( wrapper.find("label[for='email']").classes() ).toEqual(expect.arrayContaining(errors)); // bad false - classes do not containing error class

  });

});

【问题讨论】:

    标签: javascript vue.js vuejs2 vuetify.js vue-test-utils


    【解决方案1】:

    您应该为每个测试清理已安装的组件。例如使用beforeEach():

    describe("Validate login form", () => {
      // ...
      let wrapper;
      beforeEach(() => {
        wrapper = mount(Login, {
          types,
          r,
          i18n,
          store,
          data () {
              return {
              ...values
              }
          }
          })
      });
    // ...
    

    【讨论】:

    • 谢谢。但我尝试使用此选项。我还尝试在每个it() 方法的末尾使用wrapper.destroy()。在您的版本中,DOM 根本不响应触发器。触发器本身有效,因为验证器完成了它的工作并且wrapper.vm.$v.email.$error 得到空字段错误。但是 DOM 保持不变。 PS 另外,在您的版本中,单个启动it() 会在 DOM 中给出否定结果
    • 如何将attachToDocument 选项设置为true
    • 感谢您的帮助。但是我在两个选项中都使用了这个选项(和真。和假。因为我还在学习测试),你和我的版本(关于wrapper.destroy()我记得,我知道,我阅读了这个选项的描述)。但这并不影响结果。在beforeEach 中,这两个测试都不起作用,即使是单独的,无论选项的可用性及其状态如何。 DOM 忽略了这两个测试并保持不变(因为触发器和验证器都可以正常工作)。
    • attachToDocument 任何值都不会影响 DOM。在与工厂相同的版本中 - 该选项不会影响结果。但测试只能单独工作。 PS 我只使用toMatchSnapshot 将 HTML 渲染到文件中。我清理文件
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-05
    • 2020-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多