Search code examples
node.jsmockingmocha.jssinonstub

Unable to stub an exported function with Sinon


I need to test the following createFacebookAdVideoFromUrl() that consumes a retryAsyncCall that I'd like to stub with Sinon :

async function createFacebookAdVideoFromUrl(accountId, videoUrl, title, facebookToken = FACEBOOK_TOKEN, options = null, businessId = null) {
  const method = 'POST';
  const url = `${FACEBOOK_URL}${adsSdk.FacebookAdsApi.VERSION}/${accountId}/advideos`;

  const formData = {
    access_token: businessId ? getFacebookConfig(businessId).token : facebookToken,
    title,
    name: title,
    file_url: videoUrl,
  };

  const callback = () => requestPromise({ method, url, formData });

  const name = 'createFacebookAdVideoFromUrl';
  const retryCallParameters = buildRetryCallParameters(name, options);

  const adVideo = await retryAsyncCall(callback, retryCallParameters);

  logger.info('ADVIDEO', adVideo);

  return { id: JSON.parse(adVideo).id, title };
}

This retryAsyncCall function is exported as such:

module.exports.retryAsyncCall = async (callback, retryCallParameters, noRetryFor = [], customRetryCondition = null) => {
 // Implementation details ...
}

Here is how I wrote my test so far:

it.only("should create the video calling business's Facebook ids", async () => {
        const payload = createPayloadDataBuilder({
          businessId: faker.internet.url(),
        });

        const retryAsyncCallStub = sinon.stub(retryAsyncCallModule, 'retryAsyncCall').resolves('random');

        const createdFacebookAd = await FacebookGateway.createFacebookAdVideoFromUrl(
          payload.accountId,
          payload.videoUrl,
          payload.title,
          payload.facebookToken,
          payload.options,
          payload.businessId,
        );

        assert.strictEqual(retryAsyncCallStub.calledOnce, true);
        assert.strictEqual(createdFacebookAd, { id: 'asdf', title: 'asdf' });
      });

I don't expect it to work straightaway as I am working in TDD fashion, but I do expect the retryAsyncCall to be stubbed out. Yet, I am still having this TypeError: Cannot read property 'inc' of undefined error from mocha, which refers to an inner function of retryAsyncCall.

How can I make sinon stubbing work?


Solution

  • I fixed it by changing the way to import in my SUT :

    // from 
    const { retryAsyncCall } = require('../../../helpers/retry-async');
    // to
    const retry = require('../../../helpers/retry-async');
    

    and in my test file :

    // from 
    import * as retryAsyncCallModule from '../../../src/common/helpers/retry-async';
    // to
    import retryAsyncCallModule from '../../../src/common/helpers/retry-async';
    

    The use of destructuring seemed to make a copy instead of using the same reference, thus, the stub was not applied on the right reference.