Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

196
Vistas
Get sinon to resolve a promise when stubbed function is called

I have a set of integration tests for message queueing code (over a real RabbitMQ). The tests are verifying that the correct use case is triggered when a specific message arrives.

it("should trigger the use case", () => {
  const stub = sinon.stub(app, 'useCaseToTrigger').resolves();
  await publishMessage({ id: "SOME_ID" })
  // FAIL - Message isn't processed yet.
  stub.should.have.been.calledWith(match({id: "SOME_ID" }))
})

This doesn't work. The await statement waits for the message to be published, but says nothing of when the message is processed.

I can add a delay, but that quickly becomes a huge waste of time (if there are multiple tests).

it("should trigger the use case", () => {
  const stub = sinon.stub(app, 'useCaseToTrigger').resolves();
  await publishMessage({ id: "SOME_ID" })
  await new Promise(r => setTimeout(r, 100));
  // PASS - the message has been processed before the verification
  stub.should.have.been.calledWith(match({id: "SOME_ID" }))
})

But if I make the stubbed function resolve a promise when called, I can get my test to work without any undue delay.

it("should trigger the use case", () => {
  const promise = new Promise(r => {
    sinon.stub(app, "useCaseToTrigger").callsFake(() => {
      setImmediate(() => { r(); }) // Push to the end of the event loop
      return Promise.resolve();
    })
  })
  await publishMessage({ id: "SOME_ID" })
  await promise;
  // PASS - Message processed before continuing test
  app.useCaseToTrigger.should.have.been.calledWith(match({id: "SOME_ID" }))
})

This does become a bit cumbersome to deal with (and probably not the easiest to read either). But it also gives eslint floating promises warnings. So to avoid those warnings, I need to rewrite it to:

it("should trigger the use case", () => {
  await Promise.all([
    new Promise(r => {
      sinon.stub(app, "useCaseToTrigger").callsFake(() => {
        setImmediate(() => { r(); }) // Push to the end of the event loop
        return Promise.resolve();
      })
    }),
    publishMessage({ id: "SOME_ID" })
  ]);
  // PASS - Message processed before continuing test
  app.useCaseToTrigger.should.have.been.calledWith(match({id: "SOME_ID" }))
})

Is there a way to make this cleaner.

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

I think you can use an empty promise to await, so the app logic eventually resolves that promise when it is called. Sinon provides a promise fake that makes this a bit easier than creating a new Promise with an external reference to the resolve function.

const p = sinon.promise()
const stub = sinon.stub(app, 'useCaseToTrigger').callsFake(p.resolve)
await publishMessage({ id: "SOME_ID" })
await p
sinon.assert.calledWith(stub, { id: "SOME_ID" })

It looks like sinon uses Promise.resolve at the time of the stub call, so it doesn't have a reference to the eventual promise at stub creation, otherwise a stub.promise type of reference might be useful here.

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda