Mi SUT (clase SoundPlayerConsumer ) crea múltiples instancias de una clase que necesito simular ( SoundPlayer ). ¿Cómo puedo burlarme de esta clase SoundPlayer para que devuelva un objeto determinista cada vez que se llama?
Por ejemplo, mis clases:
// sound-player.js module.exports = class SoundPlayer { constructor(sound) { this.sound = sound; } playSound() { console.log(`Playing ${sound}`); } } // sound-player-consumer.js module.exports = class SoundPlayerConsumer { constructor(soundPlayer) { this.helloSound = new SoundPlayer('hello'); this.goodbyeSounnd = new SoundPlayer('goodbye'); } playSounds() { this.helloSound.playSound(); this.goodbyeSounnd.playSound(); } }Lo que estoy tratando de lograr (algo así):
// sound-player-consumer.test.js const mockHelloPlayer = { playSound: jest.fn() }; const mockGoodbyePlayer = { playSound: jest.fn() }; jest.mock('./sound-player', () => { return jest.fn() // constructor function .mockReturnValueOnce(mockHelloPlayer) // first returns the hello player .mockReturnValueOnce(mockGoodbyePlayer); // then returns the goodbye player }); test('hello then goodbye', () => { const consumer = new SoundPlayerConsumer(); consumer.playSounds(); expect(mockHelloPlayer.playSound).toBeCalled(); expect(mockGoodbyePlayer.playSound).toBeCalled(); expect(mockHelloPlayer.playSound.mock.invocationCallOrder[0]) .toBeLessThan(mockGoodbyePlayer.playSound.mock.invocationCallOrder[0]); });Esta prueba arroja un error:
TypeError: this.helloSound.playSound no es una función
He leído los documentos varias veces y todavía no entiendo completamente el enfoque de fábrica de módulos, pero este error tiene algo que ver con mis objetos simulados "no envueltos en una función de flecha y, por lo tanto, accedidos antes de la inicialización después de izar"
Estoy seguro de que hay algo realmente obvio que me estoy perdiendo aquí. ¡Cualquier ayuda apreciada!