【问题标题】:Vue-test-utils: using $nextTick multiple times in a single testVue-test-utils:在单个测试中多次使用 $nextTick
【发布时间】:2018-07-22 22:15:46
【问题描述】:

我正在为我的组件中的vuelidate 验证编写单元测试。我发现$touch()方法是异步调用的,所以我需要将$nextTick()用于expect()。当我需要两个nextTick()s 用于两个expect()s 时,就会出现问题。

describe('Validations', () => {
    let data
    let myComponent
    beforeEach(() => {
        data = () => {
            propertyABC = 'not allowed value'
        }
        myComponent = localVue.component('dummy', {template: '<div></div>', validations, data})

    it('Properly validates propertyABC', (done) => {
        Vue.config.errorHandler = done
        let wrapper = mount(myComponent, {localVue})
        wrapper.vm.$v.$touch()

        wrapper.vm.$nextTick(() => {
            expect(wrapper.vm.$v.propertyABC.$error).to.be.true
            # fails, because propertyABC === 'allowed value', adn thus $error is false
            done()
        }

        wrapper.vm.propertyABC = 'allowed value'
        wrapper.vm.$v.propertyABC.$touch()

        wrapper.vm.$nextTick(() => {
            expect(wrapper.vm.$v.proprtyABC.$error).to.be.false
            done()
        }
    })
})

如何运行此测试而不将其拆分为两个单独的测试?我认为嵌套$nextTick() 可能会起作用,但对于更多的测试它会不够灵活。

【问题讨论】:

标签: javascript vue.js vue-test-utils vuelidate


【解决方案1】:

如果您能够使用async functions,那么您可以通过await 调用$nextTick。这样可以避免嵌套它们,并将所有内容都放在同一个测试中。

像这样:

describe('Validations', () => {
  let data;
  let myComponent;
  beforeEach(() => {
    data = () => ({ propertyABC = 'not allowed value' });
    myComponent = localVue.component('dummy', {template: '<div></div>', validations, data});
  });

  it('Properly validates propertyABC', async  () => {
    let wrapper = mount(myComponent, {localVue});
    wrapper.vm.$v.$touch();

    await wrapper.vm.$nextTick();

    expect(wrapper.vm.$v.propertyABC.$error).to.be.true;

    wrapper.vm.propertyABC = 'allowed value';
    wrapper.vm.$v.propertyABC.$touch();

    await wrapper.vm.$nextTick();

    expect(wrapper.vm.$v.proprtyABC.$error).to.be.false;
  })
})

【讨论】:

    【解决方案2】:

    另一种方法是使用flushPromises。

    import flushPromises from 'flush-promises';
    ...
    
    test('some async test', async () => {
      const wrapper = mount(MyComponent, { localVue });
      wrapper.vm.$v.$touch();
      await flushPromises();
    });
    

    flushPromises() 本身返回一个 Promise,因此当您需要/想要使用 .then().then() 等链接事物时它很有用...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-24
      • 2021-04-03
      • 1970-01-01
      • 2019-07-16
      • 2019-04-17
      • 2021-09-11
      • 2021-06-12
      • 2020-12-01
      相关资源
      最近更新 更多