Vue:单元测试动态工具

问题描述

我有一个组件,其中添加一个字段组(label,input和errors)。根据从父组件接收到的prop(settings.input.component),动态导入了input元素。

我想测试此组件,以便了解行为是否正确并执行预期的操作。

问题是我无法模拟输入组件的导入,因此当我寻找不存在的元素时。

您有什么建议吗?

组件-导入动态

<template>
    <div class="field position--relative">
        <label>
          ....
        </label>
            <component
                :is="inputComponent"
                ...
            />
    </div>
</template>

<script>
export default {
    props: {
        settings: Object
    },data () {
        return {
            inputComponent: null,};
    },...
    watch: {
        'settings.input.component': {
            immediate: true,deep: false,async handler ( newComponent ) {
                // get input component
                this.inputComponent = () => import(
                    /* webpackChunkName: '[request]' */
                    `@/components/dynamic/inputs/${newComponent}`
                ).then( chunk => chunk.default || chunk );
            }
        },}
};
</script>

测试

import { shallowMount,createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';
import Vuelidate from 'vuelidate';
import { resetState } from '../helpers/index';
import store from '@/store/';
import BaseField from '@/components/bundles/fields/BaseField';

const localVue = createLocalVue();
localVue.use( Vuex );
localVue.use( Vuelidate );

describe( 'components',() => {
    // antes de cada teste,é feito
    // o reset a store
    beforeEach( resetState );
    describe( 'fields',() => {
        it( 'add field to store',() => {
            // define settings of component
            const wrapper = shallowMount( BaseField,{
                propsData: {
                    settings: {
                        input: {
                            component: 'InputBasic'
                        },}
                },});

            // find input
            const input = wrapper.find( 'input' );

            console.log( input );
            console.log( wrapper.html() );
        });
    });
});

结果

enter image description here

解决方法

我想出了如何解决这个问题。我需要刷新承诺。

这是一个测试工作的例子。

import { shallowMount,createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';
import Vuelidate from 'vuelidate';
import VueCompositionAPI from '@vue/composition-api';
import BaseField from '@/components/bundles/fields/BaseField';
import { resetState } from '../helpers/index';

const localVue = createLocalVue();
localVue.use( Vuex );
localVue.use( Vuelidate );
localVue.use( VueCompositionAPI );

function flushPromises () {
    return new Promise( resolve => setImmediate( resolve ) );
}

describe( 'components',() => {
    beforeEach( resetState );
    describe( 'fields',() => {
        it( 'add',async () => {
            const wrapper = shallowMount( BaseField,{
                propsData: {
                       ...
                    }
                },localVue
            });

            await flushPromises();

            const input = wrapper.find( '.field__input' );

            await input.setValue( 'my@mail.com' );
            input.trigger( 'blur' );

            expect( input.element.value ).toBe( 'my@mail.com' );

            expect( wrapper.vm.$data.value ).toBe( 'my@mail.com' );
        });
    });
});

刷新承诺:

function flushPromises () {
    return new Promise( resolve => setImmediate( resolve ) );
}