Vue.js test: unit с test-utils и Jest: вложенный компонент. Можно ли смоделировать $ emit (функцию) из дочернего компонента? - PullRequest
0 голосов
/ 19 сентября 2018

С учетом вложенных компонентов

компонент 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>

Можно ли протестировать родительский Heading.vue, используя shallowMount (), высмеивающий событие $ emit ("playerStop") ...?

     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);
     });

UPDATE

Я безуспешно пытался найти 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 () должен выполняться кнопкой остановки в подкомпоненте, который не заглушен.на этом уровне .. Есть ли в любом случае, чтобы заглушить это?Я хочу избежать монтирования ... использование shallowMount должно быть достаточным на этом уровне тэтов ...

спасибо за отзыв

1 Ответ

0 голосов
/ 20 сентября 2018

решено ... это одна из ловушек, которую следует избегать при модульном тестировании 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);
  });
...