代码之家  ›  专栏  ›  技术社区  ›  Steven Lambert

如何使用返回任何元素数组的呈现函数对Vue.js函数组件进行单元测试?

  •  2
  • Steven Lambert  · 技术社区  · 6 年前

    在Vue.js中,功能组件可以使用 render 功能即 returns an array of createdElements .

    export default {
      functional: true,
      props: ['cellData'],
      render: function (h, context) {
        return [
          h('td', context.props.cellData.category),
          h('td', context.props.cellData.description)
        ]
      }
    }
    

    这很好,但是我在尝试为这样的组件创建单元测试时遇到了困难。使用 shallowMount 在组件上导致 [Vue warn]: Multiple root nodes returned from render function. Render function should return a single root node.

    import { shallowMount } from '@vue/test-utils'
    import Cell from '@/components/Cell'
    
    wrapper = shallowMount(Cell, {
      context: {
        props: {
          cellData {
            category: 'foo',
            description: 'bar'
          }
        }
      }
    });
    

    This github issue 建议组件需要包装在单个根节点中才能实际呈现,但尝试这样做会导致 [vue-test-utils]: mount.context can only be used when mounting a functional component

    import { shallowMount } from '@vue/test-utils'
    import Cell from '@/components/Cell'
    
    wrapper = shallowMount('<div><Cell></div>', {
      context: {
        props: {
          cellData {
            category: 'foo',
            description: 'bar'
          }
        }
      }
    });
    

    那么,如何测试返回多个根节点的功能组件呢?

    2 回复  |  直到 6 年前
        1
  •  2
  •   Husam Ibrahim    6 年前

    您可以创建一个更高阶、透明的包装组件,将所有属性和事件侦听器传递到内部 Cell 组件使用 v-bind="$attrs" [1] v-on="$listeners" [2] . 然后你可以用 propsData 将props传递给包装组件。

    import { mount } from '@vue/test-utils'
    import Cell from '@/components/Cell'
    
    const WrappedCell = {
      components: { Cell },
      template: `
        <div>
          <Cell v-bind="$attrs" v-on="$listeners" />
        </div>
      `
    }
    
    const wrapper = mount(WrappedCell, {
      propsData: {
        cellData: {
          category: 'foo',
          description: 'bar'
        }
      }
    });
    
        2
  •  2
  •   Munim Munna Gandalf    6 年前

    您可以创建一个 fragment_wrapper 用于用片段(多个根元素)包装组件。

    //File: fragment_wrapper.js
    
    exports.fragment_wrapper = function(FragmentComponent){
      const wrapper = {
        components: { FragmentComponent },
        props: FragmentComponent.props,
        template: `<div><FragmentComponent v-bind="$props" v-on="$listeners"/></div>`
      }
      return wrapper;  
    }
    

    然后,您可以使用它测试所有零碎的组件,如下所示:

    import { mount } from '@vue/test-utils'
    import { fragment_wrapper } from './fragment_wrapper'
    import Cell from './components/Cell'
    
    
    describe('Test Cell', () => {
      let WrappedCell = fragment_wrapper(Cell);
      const wrapper = mount(WrappedCell, {
        propsData: {
          cellData: {
            category: 'foo',
            description: 'bar'
          }
        }
      });
    
      it('renders the correct markup', () => {
        expect(wrapper.html()).toContain('<td>foo</td>')
      });
    });