如何在 vue 2 的组件的根元素上测试事件?
How to test events on the root element of component in vue 2?
我正在为以下组件编写单元测试:
<template>
<sub-component
@foo="bar"
/>
</template>
<script>
import SubComponent from './SubComponent';
export default {
name: 'MyComponent',
components: { SubComponent },
methods: {
bar(payload) {
this.$emit('baz', ...payload);
}
}
}
</script>
测试将是:
import { shallowMount } from '@vue/test-utils';
import _ from 'lodash';
import MyComponent from '../../components/MyComponent';
describe('MyComponent.vue', () => {
let wrapper;
beforeEach(() => {
wrapper = shallowMount(MyComponent);
});
it('should emit baz on subcomponent foo', () => {
const subComp = wrapper.find('sub-component-stub');
expect(subComp.exists()).toBe(true); // passes
subComp.vm.$emit('foo');
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.emitted().baz).toBeTruthy(); // does not pass;
// upon logging:
console.log(_.isEqual(wrapper, subComp)); // => true
})
})
})
这个例子过于简单了,但这里的原则是我想要一个可重用的 <sub-component>
(模态)和围绕它的各种功能包装器(与模态类型执行的一个特定任务相关)映射附加功能。我不想要父组件中的功能,因为它会违反 DRY - 我必须将它放在包含特定类型模态的每个组件中。
如果 <sub-component>
不是 <template>
的直系子代,这会很好地工作。不知何故,wrapper
和 subComp
似乎托管在同一元素上。
应该如何正确测试?
显然,为了测试从组件的根元素发出的事件(并避免根元素承载 subComp.vm
和 wrapper.vm
),需要从 [= 创建一个包装器13=]:
it('should emit baz on subcomponent foo', () => {
const subComp = createWrapper(wrapper.vm.$children[0]);
expect(subComp.exists()).toBe(true);
expect(wrapper.emitted().baz).toBeFalsy();
subComp.vm.$emit('foo');
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.emitted().baz).toBeTruthy();
})
})
另一种可能性是在 dom 中找到您的元素并检查根组件的发射值。
import { shallowMount } from '@vue/test-utils'
import MyComponent from './MyComponent.vue'
import SubComponent from './SubComponent.vue'
describe('MyComponent', () => {
it('should emit baz on subcomponent foo', () => {
const wrapper = shallowMount(MyComponent)
const subComponent = wrapper.find(SubComponent)
expect(subComponent.exists()).toBe(true)
expect(wrapper.emitted('baz')).toBeUndefined()
subComponent.vm.$emit('foo', ['hello'])
expect(wrapper.emitted('baz')[0]).toEqual(['hello'])
// or expect(wrapper).toEmit('baz', 'hello') cf. below for toEmit
})
})
如果您想要 Jest 的自定义匹配器:
toEmit(received, eventName, data) {
if (data) {
expect(received.emitted()[eventName][0]).toEqual([data])
} else {
expect(received.emitted()[eventName][0]).toEqual([])
}
return { pass: true }
}
我正在为以下组件编写单元测试:
<template>
<sub-component
@foo="bar"
/>
</template>
<script>
import SubComponent from './SubComponent';
export default {
name: 'MyComponent',
components: { SubComponent },
methods: {
bar(payload) {
this.$emit('baz', ...payload);
}
}
}
</script>
测试将是:
import { shallowMount } from '@vue/test-utils';
import _ from 'lodash';
import MyComponent from '../../components/MyComponent';
describe('MyComponent.vue', () => {
let wrapper;
beforeEach(() => {
wrapper = shallowMount(MyComponent);
});
it('should emit baz on subcomponent foo', () => {
const subComp = wrapper.find('sub-component-stub');
expect(subComp.exists()).toBe(true); // passes
subComp.vm.$emit('foo');
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.emitted().baz).toBeTruthy(); // does not pass;
// upon logging:
console.log(_.isEqual(wrapper, subComp)); // => true
})
})
})
这个例子过于简单了,但这里的原则是我想要一个可重用的 <sub-component>
(模态)和围绕它的各种功能包装器(与模态类型执行的一个特定任务相关)映射附加功能。我不想要父组件中的功能,因为它会违反 DRY - 我必须将它放在包含特定类型模态的每个组件中。
如果 <sub-component>
不是 <template>
的直系子代,这会很好地工作。不知何故,wrapper
和 subComp
似乎托管在同一元素上。
应该如何正确测试?
显然,为了测试从组件的根元素发出的事件(并避免根元素承载 subComp.vm
和 wrapper.vm
),需要从 [= 创建一个包装器13=]:
it('should emit baz on subcomponent foo', () => {
const subComp = createWrapper(wrapper.vm.$children[0]);
expect(subComp.exists()).toBe(true);
expect(wrapper.emitted().baz).toBeFalsy();
subComp.vm.$emit('foo');
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.emitted().baz).toBeTruthy();
})
})
另一种可能性是在 dom 中找到您的元素并检查根组件的发射值。
import { shallowMount } from '@vue/test-utils'
import MyComponent from './MyComponent.vue'
import SubComponent from './SubComponent.vue'
describe('MyComponent', () => {
it('should emit baz on subcomponent foo', () => {
const wrapper = shallowMount(MyComponent)
const subComponent = wrapper.find(SubComponent)
expect(subComponent.exists()).toBe(true)
expect(wrapper.emitted('baz')).toBeUndefined()
subComponent.vm.$emit('foo', ['hello'])
expect(wrapper.emitted('baz')[0]).toEqual(['hello'])
// or expect(wrapper).toEmit('baz', 'hello') cf. below for toEmit
})
})
如果您想要 Jest 的自定义匹配器:
toEmit(received, eventName, data) {
if (data) {
expect(received.emitted()[eventName][0]).toEqual([data])
} else {
expect(received.emitted()[eventName][0]).toEqual([])
}
return { pass: true }
}