'aws-mock-sdk s3.getObject not working

This is my lambda handler where i am using various AWS services.

exports.handler = function(event,context){
    var body = event;
    var isValidBody = validate.doValidation(body);

    var s3DetailsObj = {
        eTag: body.s3Details.eTag, 
        location: body.s3Details.location,
        key: body.s3Details.key,
        bucket: body.s3Details.bucket
    }
    var s3DeletionErrorObject = {
        status : "SERVER_ERROR",
        sourceUid : body.sourceUid,
        s3Details : s3DetailsObj
    };

    if(isValidBody.status){
        console.log("Request validation successfull");
        async.waterfall([
            function downloadFromS3(uploadToGlacier){
                //console.log('KEY ====== :',body.s3Details.key);
                var params = {
                        Bucket: 'imagebucketgsk',
                        Key: body.s3Details.key
                    };
                s3.getObject(params,function(error, response){
                    //console.log("Into S3 get object");
                    if(!error){
                        //console.log('Repsonse = ', response.Body);
                        uploadToGlacier(null,response);
                    }else{
                        //console.error("S3 get error : ", error);
                        context.succeed(s3DeletionErrorObject);
                    }
                });
            },
            function uploadToGlacier(response, deleteFromS3){
                var params = {
                    vaultName: vaultName,
                    body: response.Body
                };
                glacier.uploadArchive(params, function(error, response){
                    if(!error){
                        deleteFromS3(null,response);
                    }else{
                        console.error("Galcier error : ", error);
                        context.succeed(s3DeletionErrorObject);
                    }
                });
            },
            function deleteFromS3(glacierData, done){
                var params = {
                    Bucket : s3Bucket,
                    Key: body.s3Details.key
                };

                s3.deleteObject(params, function(error, response){
                    if(!error){
                        var s3AndGlacierResponseObject = {
                            status : 'OK',
                            glacierLocation : glacierData.location,
                            glacierChecksum : glacierData.checksum,
                            glacierArchiveId : glacierData.archiveId,
                            s3deleteMarker : response.DeleteMarker,
                            s3DeleteVersionId : response.VersionId,
                            s3DeletedImageSourceUid : body.sourceUid,
                            s3DeletedKey : body.s3Details.key 
                        }
                        context.succeed(s3AndGlacierResponseObject);    
                    }else{
                        console.error('Deletion from s3 failed', error);
                        context.succeed(s3DeletionErrorObject);
                    }
                });
            }
        ], function(error, glacierResponse, deletedImageResponse){
                console.log('Glacier details : ', glacierResponse);
                console.log('Deleted image : ', deletedImageResponse);
        });
    }
};

This is my test cases where i want to mock the above used services. But when the mocks are not getting invoked. There are no errors.

var chai = require('chai');
var AWSMock = require('aws-sdk-mock');
var index = require('../index');

describe('Testing the image delete function', function(){
    describe('Testing the validity of the request', function(){
        it('should delete image as all the fields are valid in the request', function(done){
      var context = {
        succeed : function(result){
          console.log(result);
          done();
        } 
      };

      AWSMock.mock('S3', 'getObject', function(parmas,callback){
        console.log("Callback received for getObject");
        callback(null,'Success');
      });


      AWSMock.mock('Glacier','uploadArchive', function(params,callback){
        callback(null,{'DeleteStatus': true 
          ,'glacierLocation': 'LOCATION' 
          ,'glacierChecksum': 'CHECKSUM' 
          ,'glacierArchiveId': 'ARCHIVE ID'})
      });

      AWSMock.mock('S3', 'deleteObject', function(param,callback){
        callback(null,{'s3deleteMarker': true 
          ,'s3DeleteVersionId': 'VERSION ID' 
          ,'s3DeletedImageSourceUid': 'SOURCE' 
          ,'s3DeletedKey': 'KEY'});
      });

    index.handler({
        'sourceUid': 'UID' 
        ,'s3Details': {
          'eTag': 'ETAG' 
          ,'location': 'LOCATION' 
          ,'key': 'KEY' 
          ,'bucket': 'BUCKET'
        }
      },context);
        });
    })
}); 

But non of the mocks are getting invoked. Kindly help.



Solution 1:[1]

Try declaring the s3 variable inside the lambda's handler function:

exports.handler = function(event,context){
   var s3 = new aws.S3();
}

Solution 2:[2]

In addition to declaring s3 variable inside the handler, when mocking getObject response the Body attribute in response can be set.

AWS.mock("S3", "getObject", function(parmas, callback) {
    callback(null, {
        Body: Buffer.from(require("fs").readFileSync("file.json"))
    })
})

Solution 3:[3]

Instantiate S3 on the first function call and save it between lambda invocations:

let s3;
exports.handler = function(event,context){
    if(!s3) s3 = new aws.S3();  
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Adrian Mole
Solution 2 vinaya
Solution 3 FelixRe_