Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

187
Views
Sinon ignora la siguiente llamada asíncrona

Necesito verificar que todas las llamadas de transacción se hayan realizado correctamente. Aquí está el ejemplo:

module.js

 const functionUnderTest = async (helper) => { await helper.transaction(async (transaction) => { await helper.doSomething(); await helper.doSomething2(); await helper.expectedToBeCalled(); console.log("done"); }); }; module.exports = { functionUnderTest, };

El problema viene, que por alguna razón con sinon no puedo verificar que la última llamada se haya realizado, sin embargo, siempre se imprime el mensaje "hecho".

Aquí cómo se ve la salida

 $ npm run test > sinon-test@1.0.0 test > mocha module ✔ the former function should be called done 1) the latter function should be called done 1 passing (7ms) 1 failing 1) module the latter function should be called: AssertionError: expected stub to have been called at least once, but it was never called at Context.<anonymous> (test/module.test.js:31:48) at processTicksAndRejections (node:internal/process/task_queues:96:5)

Las pruebas en sí se representan a continuación.

helpers/chai.js

 const chaiAsPromised = require("chai-as-promised"); const chaiSinon = require("sinon-chai"); chai.use(chaiSinon); chai.use(chaiAsPromised); module.exports = { expect: chai.expect };

test/module.test.js

 const { expect } = require("./helpers/chai"); const sinon = require("sinon"); const { functionUnderTest } = require("../module"); describe("module", function () { let sandbox; let mockHelper; const transaction = {}; beforeEach(function () { sandbox = sinon.createSandbox(); mockHelper = { transaction: sandbox.stub().callsArgWithAsync(0, transaction), doSomething: sandbox.stub().resolves({}), doSomething2: sandbox.stub().resolves({}), expectedToBeCalled: sandbox.stub().resolves({}), }; }); afterEach(function () { sandbox.restore(); }); it("the former function should be called", async function () { await functionUnderTest(mockHelper); expect(mockHelper.doSomething).to.be.called; }); it("the latter function should be called", async function () { await functionUnderTest(mockHelper); expect(mockHelper.expectedToBeCalled).to.be.called; }); });

Para que sea completo y fácil de probar, he creado un repositorio con el que puedes jugar: https://github.com/vichugunov/sinon-test

mi pregunta son:

  • ¿como es posible?
  • ¿Qué estoy haciendo mal?

PD: si la llamada await helper.doSomething2() está comentada, las pruebas están pasando

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

No entiende las versiones asíncronas callsArg* y yields* para stubs. Vea este PR , la diferencia es que las versiones asíncronas callsArg* harán lo siguiente:

  • En el entorno Node, la devolución de llamada se difiere con process.nextTick .
  • En un navegador, la devolución de llamada se difiere con setTimeout(callback, 0) .

No espera a que se complete la función de devolución de llamada asincrónica. async/await en el caso de prueba solo puede esperar a que se complete la función asíncrona await helper.transaction() , no su devolución de llamada asíncrona.

La versión de sincronización de callsArg* llamará a la devolución de llamada inmediatamente. Puede echar un vistazo a este problema , cuando debería usar versiones asincrónicas callsArg* .

Por lo tanto, cuando el caso de prueba realiza una aserción, la función asincrónica como helper.expectedTobecalled() no se completa.

Debe usar callsFake() para proporcionar una devolución de llamada de código auxiliar asíncrono para el método helper.transaction() e invocarlo con async/await .

P.ej

module.js :

 const functionUnderTest = async (helper) => { await helper.transaction(async (transaction) => { await helper.doSomething(); await helper.doSomething2(); await helper.expectedToBeCalled(); console.log('done'); }); }; module.exports = { functionUnderTest };

module.test.js :

 const sinon = require('sinon'); const { functionUnderTest } = require('./module'); describe('module', function () { let sandbox; let mockHelper; const transaction = {}; beforeEach(function () { sandbox = sinon.createSandbox(); mockHelper = { transaction: sandbox.stub().callsFake(async (callback) => { await callback(transaction); }), doSomething: sandbox.stub().resolves({}), doSomething2: sandbox.stub().resolves({}), expectedToBeCalled: sandbox.stub().resolves({}), }; }); afterEach(function () { sandbox.restore(); }); it('the former function should be called', async function () { await functionUnderTest(mockHelper); sinon.assert.calledOnce(mockHelper.doSomething); }); it('the latter function should be called', async function () { await functionUnderTest(mockHelper); sinon.assert.calledOnce(mockHelper.expectedToBeCalled); }); });

Resultado de la prueba:

 module done ✓ the former function should be called done ✓ the latter function should be called 2 passing (5ms)
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!