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.

1 Answer 1

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()
  })
})
Sign up to request clarification or add additional context in comments.

4 Comments

This solution seems promising to me, but I got TypeError: _howler.Howl.mockImplementation is not a function..
Mhmm, what do you get when logging Howl
[Function: Howl]
mockImplementation doesn't exist

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.