Mocking a required class without actually importing it in Jest test

Khaled

Using Jest example, the required class

// sound-player.js
export default class SoundPlayer {
  constructor() {    
    // do something
  }
}

and the class being tested:

// sound-player-consumer.js
import SoundPlayer from './sound-player';

export default class SoundPlayerConsumer {
  playSomethingCool() {
    this.soundPlayer = new SoundPlayer();
  }
}

I want to test if SoundPlayerConsumer ever called (created an object of) SoundPlayer on playSomethingCool(). My understanding, it will look something like this:

import SoundPlayer from './sound-player';
import SoundPlayerConsumer from './sound-player-consumer';
jest.mock('./sound-player');

beforeEach(() => {
  SoundPlayer.mockClear();
});

it('check if the consumer is called', () => {
  const soundPlayerConsumer = new SoundPlayerConsumer();
  soundPlayerConsumer.playSomethingCool();
  expect(SoundPlayer).toHaveBeenCalledTimes(1);
});

However, in my case I don't want to import ./sound-player as it has many requirements and dependencies which is an overkill for my test, thus I just want to manually mock the class. Here's what I tried so far:

  import SoundPlayerConsumer from './sound-player-consumer'; 
  const SoundPlayer = jest.mock('./sound-player', () => {
    return function() {
      return {}
    }
  });
  it('check if the consumer is called', () => {
    const soundPlayerConsumer = new SoundPlayerConsumer();
    soundPlayerConsumer.playSomethingCool();
    expect(SoundPlayer).toHaveBeenCalledTimes(1);
  });

but this is the result I get Matcher error: received value must be a mock or spy function I have tried a couple other variations but I always ended up with the same result.

I have read into Jest Manual Mocks, but couldn't fully grasp it.

Khaled

According to Jest docs, mockImplementation can be used to mock class constructors. Thus, you may mock a class and return jest function using mockImplementation.

  import SoundPlayerConsumer from './sound-player-consumer';

  // must have a 'mock' prefix
  const mockSoundPlayer = jest.fn().mockImplementation(() => {
    return {}
  });

  const SoundPlayer = jest.mock('./sound-player', () => {
    return mockSoundPlayer
  });

  it('check if the consumer is called', () => {
    const soundPlayerConsumer = new SoundPlayerConsumer();
    soundPlayerConsumer.playSomethingCool();
    expect(SoundPlayer).toHaveBeenCalledTimes(1);
  });

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related