Home > Mobile >  Why is my sinon stub not working and trying to make a external call?
Why is my sinon stub not working and trying to make a external call?

Time:10-16

Hi I am working on making a unit test for AWS lambda written in JS. To be honest, it is my first time writing a test.

I decided to use chai, mocha, and sinon libraries. Here is my actual code

// index.js
const AWS = require("aws-sdk");
const getParam = async (path) => {
  const ssm = new AWS.SSM();
  const params = {
    Name: path,
    WithDecryption: false
  }
  
  const result = await ssm.getParameter(param).promise();
  const value = result['Parameter']['Value']
  console.log("@@", value);
  return value;
}

And here is what I got so far by reading other posts and documentation codes.

// index.test.js
const AWS = require("aws-sdk");
AWS.config.update({ region: 'us-east-1' });

const chai = require('chai');
const expect = chai.expect;
const sinon = require("sinon");

const { getParam } = require('./index.js');

describe("test1", () => {
  if('testing', async () => {
    const ssm = AWS.SSM();
    sinon.stub(ssm, "getParameter").withArgs("testing")
      .resolve({ Parameter: { Value: "TESTING VALUE FROM PARAM STORE" } });

    const res = await getParam("Hello");

    console.log(res);
    expect("TESTING VALUE FROM PARAM STORE").to.equal("TESTING VALUE FROM PARAM STORE");
  })
})

When I ran the test, it asked for AWS secrets, which made me realize that it was not how I expected this to behave.

If it works correctly, it will not bother connecting to AWS at all, I believe. And it should call getParam function and return the value from resolve function. May I know what I am missing?

Or am I misusing stub function? I read somewhere that stub function is used when we need to see what happened during the test like how many times a certain function was called and etc... However, I saw some of the posts using the stub function to do a similar thing that I am doing.

Thank you in advance.

CodePudding user response:

You're creating an instance of SSM inside your test and stubbing that, not the instance of SSM that lives inside your getParam method.

Instead, what you can do is stub against the prototype so that all instances from thereon will use stub when invoked.

sinon.stub(AWS.SSM.prototype, "getParameter")
    .withArgs("testing")
    .callsFake(() => ({
        promise: Promise.resolve({ 
            Parameter: { 
                Value: "TESTING VALUE FROM PARAM STORE"
            } 
        })
    }));

You can't use .resolves() on get Parameter too as it doesn't return a promise, that's what you're .promise() chained method is responsible for, so we have to replicate this :).

  • Related