Search code examples
javascriptpromisesinonstubspy

how do you create a stub/spy for an non-returned/parallel asynchronous function?


In this example, barStub.called === false, presumably because the execution flow of fooStub does not wait for barStub to resolve.

I also put assert(barStub.called) in a 10 sec setTimeout, and it still was uncalled.

Is there a way to stub a method like bar?

const sinon = require('sinon')
const assert = require('assert')

const functionHolder2 = {
  bar: function() {
    return Promise.resolve('bar')
  }
}

const functionHolder = {
  foo: function() {
    functionHolder2.bar()

    return Promise.resolve('foo')
  }
}

const fooStub = sinon.stub(functionHolder, 'foo').returns(Promise.resolve({}))
const barStub = sinon.stub(functionHolder2, 'bar').returns(Promise.resolve({}))

functionHolder.foo()

assert(fooStub.called) // this passes
assert(barStub.called) // this fails

Solution

  • The problem here is that a stub replaces the functionality of the function you are stubbing.

    This means that when you stub foo to return a promise, it totally replaces the original foo function.

    What you need to do is spy on foo, which will keep its original functionality and flow, while allowing you to find out if its been called and how many times etc.

    The actual stubbing of bar is correct - its just that the stub will never actually get called.


    What you want (including waiting for the foo call to finish):

    const sinon = require('sinon');
    const assert = require('assert')
    
    const functionHolder2 = {
      bar: function() {
        return Promise.resolve('bar')
      }
    }
    
    const functionHolder = {
      foo: function() {
        functionHolder2.bar()
    
        return Promise.resolve('foo')
      }
    }
    
    const fooStub = sinon.spy(functionHolder, 'foo')
    const barStub = sinon.stub(functionHolder2, 'bar').returns(Promise.resolve({}))
    
    functionHolder.foo().then(() => {
      assert(fooStub.called)
      assert(barStub.called)
    });
    

    Documentation link: http://sinonjs.org/releases/v4.1.2/spies/