Estoy aprendiendo pruebas unitarias con bromas y particularmente módulos burlones. Escribí un módulo simple en el archivo math.js con algunos métodos matemáticos:
const add = (a, b) => a + b; const subtract = (a, b) => b - a; const multiply = (a, b) => a * b; const divide = (a, b) => b / a; module.exports = { add, subtract, multiply, divide }
Luego lo incluyo en mi js principal y hago una simulación de módulo como esta:
jest.mock('./math.js'); const math = require('./math'); test("calls math.add", () => { math.add(1, 2); console.log(math.add.mock); expect(math.add).toHaveBeenCalled(); expect(math.add).toHaveBeenCalledWith(1, 2); expect(math.add).toHaveReturned(); expect(math.add).toHaveReturnedWith(3); });
Ahora, cuando ejecuto mi prueba, todas las pruebas pasan además de la última:
expect(math.add).toHaveReturnedWith(3);
En la consola veo:
● llama a math.add
expect(jest.fn()).toHaveReturnedWith(expected) Expected: 3 Received: undefined Number of returns: 1 10 | expect(math.add).toHaveBeenCalledWith(1, 2); 11 | expect(math.add).toHaveReturned(); > 12 | expect(math.add).toHaveReturnedWith(3); | ^ 13 | });
y console.log(math.add.mock) me da esto:
console.log { calls: [ [ 1, 2 ] ], instances: [ { add: [Function], subtract: [Function], multiply: [Function], divide: [Function] } ], invocationCallOrder: [ 1 ], results: [ { type: 'return', value: undefined } ], lastCall: [ 1, 2 ] }
Entonces parece que la función simulada math.add no devuelve ningún valor. Mi pregunta es ¿por qué? ¿Qué hice mal?
Después de usar jest.mock('someModule')
, jest creará una versión simulada automáticamente para este módulo. Esto significa que todas las cosas exportadas de este módulo se burlan.
Puedes pensar que el método math.add
simulado es jest.fn()
. No hay una implementación simulada para ello. Si no se proporciona ninguna implementación, la función simulada devolverá undefined
cuando se invoque. Es por eso que math.add(1, 2)
devuelve undefined
.
Está probando el módulo de math
, entonces NO debe burlarse de él. Pero si insistes en hacerlo. Puede usar math.add.mockReturnValue(3);
antes de invocar math.add(1,2)
. Pero no tiene sentido, puedes dar cualquier valor que quieras. No probaste el método real math.add
. Simplemente hace coincidir su valor de retorno simulado con la afirmación expect(math.add).toHaveReturnedWith(3)
Por ejemplo math.js
:
const add = (a, b) => a + b; const subtract = (a, b) => b - a; const multiply = (a, b) => a * b; const divide = (a, b) => b / a; module.exports = { add, subtract, multiply, divide, };
math.test.js
:
const math = require('./math'); jest.mock('./math.js'); test('calls math.add', () => { math.add.mockReturnValue(3); math.add(1, 2); expect(jest.isMockFunction(math.add)).toBeTruthy(); expect(math.add).toHaveBeenCalled(); expect(math.add).toHaveBeenCalledWith(1, 2); expect(math.add).toHaveReturned(); expect(math.add).toHaveReturnedWith(3); });
Resultado de la prueba:
PASS stackoverflow/71605818/math.test.js ✓ calls math.add (3 ms) ----------|---------|----------|---------|---------|------------------- File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s ----------|---------|----------|---------|---------|------------------- All files | 100 | 100 | 20 | 100 | math.js | 100 | 100 | 20 | 100 | ----------|---------|----------|---------|---------|------------------- Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 0 total Time: 1.225 s