1

I'm using Jest for unit test in a vuejs2 project but got stuck in mocking howler.js, a library imported in my component.

Suppose I have a component named Player.vue

<template>
  <div class="player">
    <button class="player-button" @click="play">Player</button>
  </div>
</template>

<script>
import { Howl } from 'howler';

export default {
  name: 'audioplayer',
  methods: {
    play() {
      console.log('player button clicked');
      new Howl({
        src: [ 'whatever.wav' ],
      }).play();
    }
  }
}
</script>

then I have its test file named Player.spec.js. Test code was written based on the answer here, but the test failed since called wasn't set as true. It seems that mocked constructor won't be called when running this test.

import Player from './Player';
import Vue from 'vue';

describe('Player', () => {
  let called = false;

  jest.mock('howler', () => ({
    Howl({ src }) {
      this.play = () => {
        called = true;
        console.log(`playing ${src[0]} now`);
      };
    },
  }));

  test('should work', () => {
    const Constructor = Vue.extend(Player);
    const vm = new Constructor().$mount();
    vm.$el.querySelector('.player-button').click();
    expect(called).toBeTruthy(); // => will fail
  })
})

Though I'm using Vuejs here, I considered it as a more general question related to the usage of Jest's mock API, but I'm not able to get further.

choasia
  • 10,404
  • 6
  • 40
  • 61

1 Answers1

1

The SO you linked to only works for react components. Here is a way to mock the module with a spy on the play function that can be tested with toBeHaveCalled

//import the mocked module
import { Howl } from 'howler'; 
// mock the module so it returns an object with the spy
jest.mock('howler', () => ({Howl: jest.fn()}));

const HowlMock ={play: jest.fn()}
// set the actual implementation of the spy so it returns the object with the play function
Howl.mockImplementation(()=> HowlMock)

describe('Player', () => {
  test('should work', () => {
    const Constructor = Vue.extend(Player);
    const vm = new Constructor().$mount();
    vm.$el.querySelector('.player-button').click();
    expect(Howl).toBeHaveCalledWith({src:[ 'whatever.wav' ]})
    expect(HowlMock.play).toBeHaveCalled()
  })
})
Ben Hare
  • 4,365
  • 5
  • 27
  • 44
Andreas Köberle
  • 106,652
  • 57
  • 273
  • 297