[英]How do you unit test a Vue.js functional component with a render function that returns any array of elements?
In Vue.js, a functional component can return multiple root nodes by using a render
function that returns an array of createdElements .在 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)
]
}
}
This works great but I'm having trouble trying to create a unit test for such a component.这很好用,但我在尝试为这样的组件创建单元测试时遇到了麻烦。 Using
shallowMount
on the component results in [Vue warn]: Multiple root nodes returned from render function. Render function should return a single root node.
在组件上使用
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'
}
}
}
});
This github issue suggests that the component needs to be wrapped in a single root node to actually render it, but trying that results in [vue-test-utils]: mount.context can only be used when mounting a functional component
这个 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'
}
}
}
});
So how do I test a functional component that returns multiple root nodes?那么如何测试一个返回多个根节点的功能组件呢?
You could create a higher order, transparent wrapper component that passes all props and event listeners to the inner Cell
component using v-bind="$attrs"
[1] and v-on="$listeners"
[2] .您可以使用
v-bind="$attrs"
[1]和v-on="$listeners"
[2]创建一个更高阶的透明包装组件,将所有道具和事件侦听器传递给内部Cell
组件。 Then you can use propsData
to pass props to the wrapper component ..然后你可以使用
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'
}
}
});
You can create a fragment_wrapper
for wrapping your Components with Fragments (multiple root elements).您可以创建一个
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;
}
Then you can use this to test all your Fragmented Components as follows:然后,您可以使用它来测试所有碎片组件,如下所示:
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.