unit-testing - Vue.js 测试:带有 test-utils 和 Jest 的单元:嵌套组件 - 是否可以从子组件模拟 $emit(function)?
问题描述
给定嵌套组件
Heading.vue 组件 {{ $t("lang.views.home.heading.btn__listen") }} play_arrow
嵌套子组件AuioPlayer.vue
<template>
<div style="display: inline-block;">
<v-btn id="playPauseBtn">
...
</v-btn>
<v-btn id="stopBtn" outline icon class="inline teal--text" @click.native="stop()">
<v-icon>stop</v-icon>
</v-btn>
<v-btn id="muteBtn">
...
</v-btn>>
</div>
</template>
<script>
...
methods: {
stop() {
this.$data._howl.stop();
this.$emit("playerStop");
},
...
</script>
是否可以使用 shallowMount() 模拟 $emit("playerStop") 事件来测试父 Heading.vue ...?
it("should display LISTEN button on child component audioplayer event stop()", () => {
// given
wrapper = shallowMount(Heading, { router, i18n });
wrapper.vm.listening = true;
// when
// audioplayer child component should be stubbed
const audioplayer = wrapper.find('#audioplayer');
console.log(audioplayer.html());
// mock the $emit(playerStop) from the child audioplayer stub
expect(wrapper.vm.listening).toBe(false);
});
更新
我验证了 2 个解决方案但没有成功
1 / 使用间谍功能
it("should display LISTEN button on child component audioplayer event stop()", () => {
// given
wrapper = shallowMount(Heading, { router, i18n });
const spy = jest.fn();
// wrapper.vm.$on('stopPlayer', spy); // focus on the call of listener
wrapper.setData({ listening: true });
const audioplayer = wrapper.find('audioplayer-stub');
// when
audioplayer.trigger('stopPlayer');
// then
expect(spy).toHaveBeenCalledTimes(1);
expect(wrapper.vm.listening).toBe(false);
});
2 / 使用异步 $emit()
it("should display LISTEN button on child component audioplayer event stop()", async () => {
// given
wrapper = shallowMount(Heading, { router, i18n });
wrapper.setData({ listening: true });
const audioplayer = wrapper.find('audioplayer-stub');
// when
audioplayer.vm.$emit('stopPlayer');
await wrapper.vm.$nextTick();
// then
expect(wrapper.vm.listening).toBe(false);
});
在这两种情况下,如果我从子组件触发或发射,似乎什么都没有发生......
事实上,应该从子组件中的停止按钮完成发射(),该按钮在此级别没有存根..反正有存根吗?我想避免坐骑......在这个级别的 tets 上使用 shallowMount 应该足够了......
感谢您的反馈
解决方案
已解决......这是单元测试 vue.js 时要避免的陷阱之一:我应该测试什么?,而不是测试错误的东西......
使用 test-utils w shallowMount,我不应该测试来自存根组件的 emi() 事件(这应该稍后在这个组件中测试)我应该只测试将被调用的方法......在这种情况下
方法: { playerStop() { this.listening = false; } }
简单地测试了
it("method playerStop should tpggle listening to false", async () => {
// given
wrapper = shallowMount(Heading, { router, i18n });
wrapper.setData({ listening: true });
// when
wrapper.vm.playerStop();
const playBtn = wrapper.find('#playBtn')
// then
expect(wrapper.vm.listening).toBe(false);
});
推荐阅读
- php - 隐式路由模型绑定
- node.js - 使用 Nodejs Sequelize 避免竞争条件
- regex - 在 bash 的 sed 命令中使用感叹号
- c# - .NET 编写事件处理程序以捕获本地异常
- import - 系统如何响应 ITIM 5.1 到 ISIM 6.0 升级后的待处理请求 DB2 转储
- android - 多屏幕支持的最佳布局配置
- java - 从 IOB 注释训练集中训练命名实体识别器模型的文档
- spring - 在 thyeleaf 中提交表格
- c++ - 如何使用 msbuild 从 OBJS 生成导入 LIB
- c - 2nd order DE Runge Kutta 4 on C