Vue-test-utils:在一次测试中多次使用$ nextTick

时间:2018-02-12 16:56:43

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

我正在为我的组件中的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()可能会起作用,但是对于更高的测试数量来说它不灵活。

2 个答案:

答案 0 :(得分:11)

如果您能够使用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;
  })
})

答案 1 :(得分:0)

另一种方法是使用flushPromises。

import flushPromises from 'flush-promises'
...

test('some asyn test', ascyn () => {
  const wrapper = mount(MyComponent, { localVue })
  wrapper.vm.$v.$touch()
  await flushPromises()
})

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