Monday 10 April 2017

aws-sdk-mock not mocking putRecord on firehose

I am trying to mock putRecord method on AWS Firehose object but mocking is not succeeding. The code ends up calling the aws-sdk api on firehose object which talks with live aws service. What is wrong in below code? what needs to be changed to avoid this live service call and make mock to be effective?

Is there a way to send a thenable object and not just plain object as it does with callback below? i.e. someway to use something like callbackFunc that I defined there in the test code?

Also eventually I need to check if the mock did get called or not. How would I achieve that? Could I use sinon.stub in some manner to achieve that so that later on I can verify? How?

Here is code and test code portions... modified to simple form for this posting.

code that is part of a file say samplelogging.js. ...

/*jshint strict:true */
/*jshint node:true */
/*jshint esversion:6 */
/*jshint mocha:true */
"use strict";

var Promise = require('bluebird');
var AWS = require('aws-sdk');
var uuid = require('uuid');

AWS.config.setPromisesDependency(Promise);

var Logger = {
    /**
     * Get's a AWS Firehose Instance 
     */
    getFirehoseInstance: function getFirehoseInstance() {
        if (!(this.firehose)) {
            this.firehose = new AWS.Firehose({apiVersion: "2015-08-04", region: "us-west-2"});
        }
        return this.firehose;
    },

    getLogger: function getLogger(options) {
        options = options || {};
        let self = this;

        self.class = options.class;
        self.firehose = self.getFirehoseInstance();

        return self;
    },


    logInfo: function logInfo(dataToLog, callback) { 
        this._log("info", dataToLog)        
            .then(function (data){
                if (callback) {
                    callback();
                }                
            });
        return;
    },

    /**
     * @api: private
     */
    _log: function _log(traceLevel, dataToLog) {

        return new Promise(function(resolve, reject) {
            var params = params || {};

            AWS.config.update({ logger: process.stdout });
            AWS.config.update({ retries: 3 });
            var recordParams = {
                type: params.type || 'LogEntry'
            };

            if (typeof dataToLog === 'string' || dataToLog instanceof String) {
                recordParams.data = { message: dataToLog };
            } else {
                recordParams.data = dataToLog;
            }

            recordParams.data.id = uuid.v1();
            recordParams.data.preciseTimestamp = Math.floor(new Date().getTime()/1000);
            recordParams.data.class = this.class;
            recordParams.data.traceLevel = traceLevel;

            var firehoseRecordParams = {
                DeliveryStreamName: "mystreamname",  //replace mystreamname with real stream name
                Record: {
                    Data: JSON.stringify(recordParams)+',\n'
                }
            };

            this.firehose.putRecord(firehoseRecordParams, function(err, recordId) {
                console.log("debug: recordId returned by putRecord = " + JSON.stringify(recordId));
                return resolve(recordId);
            });

        }.bind(this));
    }

};

module.exports = Logger;

Here is my test code that is part of a file say sampleloggingtest.js ...

var expect = require('chai').expect;
var Promise = require("bluebird");
var sinon = require("sinon");
var AWSMock = require('aws-sdk-mock');

describe.only("Logging tests", function () {

        it.only("Test AWS firehose API invoked", function (done) {

            let mylogger = Logger.getLogger({class: "Unit Test"});
            let firehoseInstance = mylogger.getFirehoseInstance();

            // want to have a callback function that returns a thenable object and not just an object. Not sure how to use it though with mock
            // so for now this is just code that shows what i intend to do.
            let callBackFunc = function( err, recordId) {
                    console.log("debug: returend from putRecord, recordId = " + JSON.stringify(recordId));
                    return Promise.resolve(recordId);
                };

            // calling mock as per the documentation at https://github.com/dwyl/aws-sdk-mock
            AWSMock.mock('Firehose', 'putRecord', function(params, callback) {
                console.log("debug: callback to putRecord to be called");                
                callback(null, {"RecordId": "12345"} );
            });

            // calling a method that should call firehose logging but our mock should intercept it - though it doesn't.
            mylogger.logInfo({ prop1: "value1" }, function(){
                console.log("debug: in the callback that was passed to logInfo...");
                done();
            });

        });
});



via mi10

No comments:

Post a Comment