我試圖在AWS Firehose對象上模擬putRecord方法,但嘲笑不成功。代碼最終調用aws-sdk api與firehose對象進行交談,並與live aws服務進行交談。下面的代碼有什麼錯誤?什麼需要改變,以避免這個現場服務電話,並使模擬有效?嘲笑putRecord on firehose不能與aws-sdk-mock一起工作
有沒有辦法發送一個可引用對象,而不僅僅是普通對象,就像它在下面的回調一樣?也就是說,在測試代碼中使用類似callbackFunc的東西呢?
最終我還需要檢查模擬是否被調用。我將如何實現這一目標?我能否以某種方式使用sinon.stub來實現這一點,以便以後可以驗證?怎麼樣?
這裏是代碼和測試代碼部分...修改爲簡單的形式發佈。
作爲文件一部分的代碼說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;
這裏是我的測試代碼是文件的一部分,說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();
});
});
});
我試圖做同樣的事情(模擬Firehose)並看到相同的結果(模擬不叫,只有真正的服務)。在aws-sdk-mock文檔中,他們的測試代碼使用var AWS = require('aws-sdk-mock'),而不是AWSMock。我不知道這是如何工作的,但如果它通過替換變量來起作用,那麼名稱可能很重要。 – mmorrisson
所以我並不孤單。 :-)希望聽到有人工作,或希望聽到AWS開發人員... 順便說一下,變量的名稱不應該改變結果。我相信你試過AWS和它沒有工作。 – mi10