Vue.js test:unit与test-utils和Jest:嵌套组件-是否可以从子组件中模拟$ emit(function)?

时间:2018-09-19 13:19:22

标签: unit-testing vue.js jestjs vue-test-utils

给出嵌套的组件

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>

是否有可能使用模拟$ emit(“ playerStop”)事件的shallowMount()测试父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);
});

在这两种情况下,如果我从子组件触发或发出,似乎都没有任何反应...
实际上,emit()应该从子组件中的停止按钮完成,该按钮在此级别上没有设置。 反正有存根吗? 我想避免坐骑...使用tweetMount在这个水平上应该足够了...

感谢您的反馈

1 个答案:

答案 0 :(得分:1)

已解决...这是在单元测试vue.js时要避免的陷阱之一:我应该测试什么?而不是测试错误的东西。...

使用test-utils wshallowMount,我不应该测试存根组件中的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);
  });