【问题标题】:How to test method calls in the same class using Jest?如何使用 Jest 测试同一类中的方法调用?
【发布时间】:2019-05-14 16:40:04
【问题描述】:

我正在尝试测试类中的函数调用以确保它们被调用,但我似乎无法弄清楚如何使用 Jest 来做到这一点。

自动模拟不起作用,使用模块工厂参数调用 jest.mock 也不起作用。

这是有问题的类,我想测试调用 play() 调用 playSoundFile()。

class SoundPlayer {
  constructor() {
    this.foo = 'bar';
  }

  playSoundFile(fileName) {
    console.log('Playing sound file ' + fileName);
  }

  play() {
    this.playSoundFile('song.mp3');
  }
}

module.exports = SoundPlayer;

这是测试文件:

const SoundPlayer = require('../sound-player');
jest.mock('../sound-player');

it('test', () => {
  const soundPlayerConsumer = new SoundPlayer();

  const coolSoundFileName = 'song.mp3';
  soundPlayerConsumer.play();

  const mockPlaySoundFile = SoundPlayer.mock.instances[0].playSoundFile;
  expect(mockPlaySoundFile.mock.calls[0][0]).toEqual(coolSoundFileName);
});

mockPlaySoundFile.mock.calls 是空的,因此会出错。

【问题讨论】:

    标签: javascript jestjs


    【解决方案1】:

    我建议你不要模拟任何内部方法。相反,您可以模拟任何外部依赖项并调用应该是公共的方法。然后,您针对 public(应该在外部调用)方法返回的内容运行断言,并检查模拟(模拟的外部依赖项)是否被调用。

    在这个特定的例子中,只有console.log:

    console.log = jest.fn();
    const soundPlayerConsumer = new SoundPlayer();
    soundPlayerConsumer.play();
    expect(console.log).toHaveBeenCalledTimes(1);
    expect(console.log).toHaveBeenCalledWith('Playing sound file song.mp3');
    

    在更真实的场景中,它可能需要您模拟 document 甚至使用 jsdom 模拟 <audio /> HTML 元素。但是方法是一样的。

    【讨论】:

    • 虽然我仍然看到测试内部代码的一些好处并且似乎不能完全放弃这个概念,但我想我正在慢慢得出同样的结论,我应该只测试公共方法.
    【解决方案2】:

    如果我不模拟整个类而只是监视函数,它就可以工作。但是,这并不能绕过测试密集型功能,例如调用数据库。

    const SoundPlayer = require('../sound-player');
    
    it('test', () => {
      const soundPlayerConsumer = new SoundPlayer();
      const playSpy = jest.fn();
      soundPlayerConsumer.playSoundFile = fileName => playSpy(fileName);
    
      soundPlayerConsumer.play();
    
      expect(playSpy).toHaveBeenCalledWith('song.mp3');
    });
    

    【讨论】:

      猜你喜欢
      • 2018-09-14
      • 2021-09-06
      • 1970-01-01
      • 2019-07-29
      • 2020-12-07
      • 1970-01-01
      • 2020-05-08
      • 1970-01-01
      • 2022-01-18
      相关资源
      最近更新 更多