1

给定嵌套组件

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 应该足够了......

感谢您的反馈

4

1 回答 1

2

已解决......这是单元测试 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);
  });
于 2018-09-20T14:07:42.877 回答