簡體   English   中英

如何使用返回任何元素數組的渲染函數對 Vue.js 功能組件進行單元測試?

[英]How do you unit test a Vue.js functional component with a render function that returns any array of elements?

在 Vue.js 中,功能組件可以通過使用返回 createdElements 數組的render函數返回多個根節點。

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. [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'
      }
    }
  }
});

這個 github 問題表明該組件需要包裝在單個根節點中才能實際呈現它,但嘗試這樣做會導致[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'
      }
    }
  }
});

那么如何測試一個返回多個根節點的功能組件呢?

您可以使用v-bind="$attrs" [1]v-on="$listeners" [2]創建一個更高階的透明包裝組件,將所有道具和事件偵聽器傳遞給內部Cell組件。 然后你可以使用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'
    }
  }
});

您可以創建一個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>')
  });
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM