我正在尝试在类中测试函数调用以确保它们被调用,但是我似乎无法弄清楚如何使用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为空,因此会出错。
答案 0 :(得分:2)
我建议您不要模拟任何内部方法。相反,您可以模拟任何外部依赖关系并调用应该公开的方法。然后,您针对 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元素。但是方法是一样的。
答案 1 :(得分:0)
如果我不嘲笑整个类,而只是监视该函数,它将起作用。但是,这无法解决测试密集功能的问题,例如调用数据库。
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');
});