web-dev-qa-db-ja.com

Vue-test-utils:単一のテストで$ nextTickを複数回使用する

コンポーネントで vuelidate 検証の単体テストを作成しています。 $touch()メソッドが非同期で呼び出されることがわかったので、$nextTick()expect()に使用する必要があります。 2つのnextTick()sに対して2つの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()
        }
    })
})
_

このテストを2つの個別のテストに分割せずに実行するにはどうすればよいですか? $nextTick()をネストすることはうまくいくと思いますが、より多くのテストには柔軟ではありません。

8
Fidd

async functions を使用できる場合は、await the $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;
  })
})
14
thanksd

別のアプローチは、flushPromisesを使用することです。

_import flushPromises from 'flush-promises'
...

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

flushPromises()はpromise自体を返すので、.then().then()などを使用して物事をチェーンする必要がある場合に役立ちます。

1
steven87vt