Search code examples
node.jsmocha.jschaiaws-sdk-jsaws-sdk-mock

NodeJS: Mock promise of aws-sdk


I am currently working on some code in NodeJS.

My code looks like this:

const AWS = require('aws-sdk');
const PARAMS_ACCOUNT = {
  AttributeNames: [
     "max-instances"
  ]
 };

const ec2 = new AWS.EC2();
const getAccountAttributes = ec2.describeAccountAttributes(PARAMS_ACCOUNT).promise();

function maxInstances() {
    return getAccountAttributes.then(data => {
        return  data.AccountAttributes[0].AttributeValues[0].AttributeValue;
    });
 }

I've tried to use aws-sdk-mock, beside chaiJS and mochaJS but I'am not sure how to mock the .promise() of the aws-sdk.

My attempt looks like the following:

const chai = require('chai');
const mocha = require('mocha');
const awsSDK = require('aws-sdk');
const aws = require('aws-sdk-mock');
const server = require('../instance_limit.js');

const expect = chai.expect;

describe('Sample test', () => {
 it('this is also a test', () => {
  aws.mock('EC2','describeAccountAttributes',function (params, callback){
    callback(null, {AccountAttributes:[{AttributeValues:[{AttributeValue: 10}]}]});
  });
  var awsEC2 = new awsSDK.EC2();
   const instances = server.maxInstances();
   expect(instances).to.equal(10);
  });
});

But with this I am not able to mock the aws-sdk call. Thanks for your help.


Solution

  • I was able to solve the problem by using the principle of dependency injection which prevents from mocking the aws sdk in this case, for that it was necessary to adjust my function a little bit and set a default value. It now looks like this:

    const AWS = require('aws-sdk');
    const PARAMS_ACCOUNT = {
      AttributeNames: [
     "max-instances"
      ]
     };
    
    const ec2 = new AWS.EC2();
    const getAccountAttributes = ec2.describeAccountAttributes(PARAMS_ACCOUNT).promise();
    
    function maxInstances(accountAttributes = getAccountAttributes()) {
        return accountAttributes.then(data => {
            return data.AccountAttributes[0].AttributeValues[0].AttributeValue;
        });
    }
    

    This now allows me to provide a sample value during the tests, like this:

    const chai = require('chai');
    const mocha = require('mocha');
    const server = require('../instance_limit.js');
    
    const expect = chai.expect;
    
    describe('data calculation based on ec2 values', () => {
     it(' expects to return max Instances value equal 10', () => {
       const accountAttributeObject = {AccountAttributes:[{AttributeValues:[{AttributeValue: 10}]}]}
       const accountAttributes = Promise.resolve(accountAttributeObject);
       const instances = server.maxInstances(accountAttributes);
    
       return instances.then( data => {
         expect(data).to.equal(10);
       });
      });
    })