dwyl / aws-sdk-mock Goto Github PK
View Code? Open in Web Editor NEW:rainbow: AWSomocks for Javascript/Node.js aws-sdk tested, documented & maintained. Contributions welcome!
License: Apache License 2.0
:rainbow: AWSomocks for Javascript/Node.js aws-sdk tested, documented & maintained. Contributions welcome!
License: Apache License 2.0
Thanks for this package, it's a real timesaver!
I am now using the Amazon Cognito SDK for JavaScript (amazon-cognito-identity-js).
https://github.com/aws/amazon-cognito-identity-js
This allows signup, sign in etc to a specified Cognito User Pool. The methods in this package call AWS.CognitoIdentityServiceProvider methods at various points.
How can I mock the CognitoIdentityServiceProvider methods in my tests, because I do not actually instantiate CognitoIdentityServiceProvider in my own code?
When trying to mock multiple methods on the same service you get a TypeError.
It would be great if you could add a license file to the repo.
At least some of the service objects in aws-sdk v2.6.x are now getter/setter-only properties. This hits an upstream bug: sinonjs/sinon#1018.
var AWS = require('aws-sdk'); // @2.6.1
var MockAWS = require('aws-sdk-mock');
MockAWS.mock('ECS', 'listTasks', function() {});
/Users/r/tmp/nope/node_modules/aws-sdk-mock/node_modules/sinon/lib/sinon/util/core.js:91
throw error;
^
TypeError: Attempted to wrap undefined property ECS as function
at checkWrappedMethod (/Users/r/tmp/nope/node_modules/aws-sdk-mock/node_modules/sinon/lib/sinon/util/core.js:78:29)
at Object.wrapMethod (/Users/r/tmp/nope/node_modules/aws-sdk-mock/node_modules/sinon/lib/sinon/util/core.js:121:21)
at Object.stub (/Users/r/tmp/nope/node_modules/aws-sdk-mock/node_modules/sinon/lib/sinon/stub.js:67:26)
at mockService (/Users/r/tmp/nope/node_modules/aws-sdk-mock/index.js:67:27)
at Object.AWS.mock (/Users/r/tmp/nope/node_modules/aws-sdk-mock/index.js:43:5)
at Object.<anonymous> (/Users/r/tmp/nope/test.js:4:9)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
I'm really trying to use this module to test our app. But I can't wrap my head around how to actually use it in a real scenario where I need to test some of the services our app is using. Here is what I'm doing:
var AWSMock = require('aws-sdk-mock');
const Resolver = require('../services/resolver');
AWSMock.mock('SQS', 'receiveMessage', function (params, callback){
callback(null, "successfully received message");
});
Resolver.start();
AWSMock.restore('SQS');
Resolver.start is a function inside the resolver service that starts the AWS sdk like so:
var AWS = require('aws-sdk');
this.sqs = options.sqs || new AWS.SQS({
region: options.region || 'eu-west-1'
});
this.sqs.receiveMessage(receiveParams, this._handleSqsResponseBound);
Nothing gets mocked and my receiveMessage doesn't get called.
I tried several things but just can't seem to get this to work. Am I ordering the includes wrong?
Well i am using serverless framework and using 'serverless-mocha-plugin' for writing tests, I have written the tests, when i run the test indvidually they are working fine but when i try to run multiple test files at the same time it passes one test but gives 'ConfigError: Missing region in config' in the other test,
to tell in detail, i have created two functions so two test files, one is an index function i.e. uses DynamoDb's scan method and the other is show function i.e. uses DynamoDb's getItem method, I mocked both the functions in their respective test files,
Please help me out here I am a novice at this Thanks in advance
Hi I've been trying to mock some APIGatway Methods but for some reason it still seems to be going through to AWS.
My code:
In my index.js
:
clearDomainName() {
return this.apigateway.deleteDomainName({domainName: this.givenDomainName}).promise();
}
In my index.test.js
:
it('Delete the domain name', function () {
AWS.mock('APIGateway', 'deleteDomainName', testDomainData);
plugin.clearDomainName().then(function (data) {
console.log(data);
done();
}).catch(done);
});
Error that I receive:
UnknownEndpoint: Inaccessible host: `apigateway.us-moon-1.amazonaws.com'. This service may not be available in the `us-moon-1' region.
Showing that the method was not mocked and things are going through to aws.
Am I doing something wrong or is this function not supported?
Thanks for the help!
I realized the current mocking breaks down on something like S3.getSignedUrl
because the replace
parameter to the mock function strictly adheres to the function(params, callback) {}
signature.
Hi @nikhilaravi,
as discussed, please add lots of comments to your amazing code so us "normal" people can understand what it'd doing... thanks! ๐
Hi I'm trying to use this library, but cannot get it to work.
node: 4.3.0
"aws-sdk": "^2.5.2",
"aws-sdk-mock": "^1.5.0",
getting this error:
TypeError: Attempted to wrap putObject which is already stubbed at checkWrappedMethod (node_modules/sinon/lib/sinon/util/core.js:84:29) at Object.wrapMethod (node_modules/sinon/lib/sinon/util/core.js:128:21) at Object.stub (node_modules/sinon/lib/sinon/stub.js:67:26) at mockServiceMethod (node_modules/aws-sdk-mock/index.js:95:54) at new <anonymous> (node_modules/aws-sdk-mock/index.js:80:7) at Function.invoke (node_modules/sinon/lib/sinon/spy.js:172:59) at proxy (eval at createProxy (node_modules/sinon/lib/sinon/spy.js:77:86), <anonymous>:1:35) at Object.uploadAttachment (api/services/FileService.js:137:12)
When using my service
function uploadAttachment(file) {
var s3 = new AWS.S3();
var params = {
...
};
var upload = s3.putObject(params).promise();
return upload
.then(function (result) {
return result;
})
.catch(function (error) {
throw new Error(error);
});
}
Test
it('should upload an attachment to a s3 bucket', function() {
AWS.mock('S3', 'putObject', 'success');
return FileService.uploadInvoiceAttachment('file.txt')
.then(function (body) {
body.should.be.true;
AWS.restore();
});
});
Hi,
We are facing some issues when running multiple tests with Mocha in conjunction with aws-sdk-mock.
If we run the following test JS individually with Mocha they work perfectly, but when run together, the second test run fails.
TestA is like:
var awsMock = require('aws-sdk-mock');
describe('Suite A', function ()
{
before(function () {
awsMock.mock('DynamoDB.DocumentClient', 'query', function (params, callback) {
...
}
}
it("Test case A", function() {
....
});
}
TestB is really similar:
var awsMock = require('aws-sdk-mock');
describe('Suite B', function ()
{
before(function () {
awsMock.mock('DynamoDB.DocumentClient', 'query', function (params, callback) {
...
}
}
it("Test case B", function() {
....
});
}
I added some debugging and it seems that the mocking method called in the second test belongs to the first test.
This might be because Mocha runs all the specs together in a single command, loading all the modules into a single test environment.
I am not sure if we can't change the Mocha behaviour, so the solution I am proposing is adding maybe a new method that would allow us to re-mock a method.
Thanks!
In trying to use this mock sdk for SES, I seem to be getting undefined for that particular service.
I'd like to throw an error whenever there's a call to any unmocked aws-sdk
method.
I opened a PR to add .createReadStream support: #50
The basic functionality is:
awsMock.mock('S3', 'getObject', new Buffer('body'));
var s3 = new AWS.S3();
var req = s3.getObject('getObject', {});
var stream = req.createReadStream();
stream.pipe(concatStream(function(actual) {
st.equals(actual.toString(), 'body')
awsMock.restore('S3', 'getObject');
st.end();
}));
Just in case anyone is interested in changing the approach here:
https://gist.github.com/wryun/347283d8e715afc4f904ffe5838c536c
(would involve a complete rewrite, but much simpler code and means that you have easy support for param validation, .promise, .eachItem, .eachPage, events, etc.)
Sometimes I would like to be able to make assertions about the configuration options that are sent to the client constructor, e.g. region or fixed params.
How difficult would it be to expose a mechanism for mocking the constructors? e.g.
AWS.mock('S3', function(config) {
assert.equal(config.region, 'eu-west-1');
});
Hi,
There seems to be an issue with version 1.6.1 when mocking the S3.uploadPart method although it looks like this could also be affecting other areas.
I have code that tries to stream upload a file to S3. If a part fails to upload, it tries again until a maximum number of retries is met. On the other hand, I have a test that makes the upload to fail the first 2 attempts and the third one completes successfully.
So, in brief, the scenario is as follows:
Problem is that the next time s3.uploadPart is called after the first failed upload, the code does NOT run thought the mock and executes the S3 original code instead.
I run the test with v1.5.0 and works just fine. This started happening in v1.6.1.
This is a sample of how my code looks like:
function uploadPart(params, callback)
{
s3.uploadPart(params, (error, data) => // This runs through the mock and returns
{
if (successful && noMorePartsToUpload)
{
callback(OK);
}
else
{
if (maximumAttemptsNotReached)
{
uploadPart(params, callback); // Recursive call with updated params
}
else
{
callback(Error);
}
}
}
}
Have you observed this issue in your tests?
Here is my module:
var AWS = require('aws-sdk')
const https = require('https')
module.exports = function () {
var s3 = new AWS.S3({
httpOptions: {
agent: new https.Agent()
},
signatureVersion: 'v4'
})
return s3.getObject({Bucket: 'somebucket', Key: 'somekey'}).promise()
}
Here is my test script:
const chai = require('chai')
const chaiAsPromised = require('chai-as-promised')
const AWS = require('aws-sdk-mock')
const myFunc = require('./myModule')
chai.use(chaiAsPromised)
const expect = chai.expect
chai.should()
describe('Get MMS API Key', function () {
before(function () {
AWS.mock('S3', 'getObject', function (params, callback) {
callback(null, 'dummy-data')
})
})
it('Should get dummy data', function () {
myFunc().should.eventually.equal('dummy-data')
})
after(function () {
AWS.restore('S3', 'getObject')
})
})
I'm getting this error in the before hook:
TypeError: Attempted to wrap undefined property S3 as function
at checkWrappedMethod (node_modules/aws-sdk-mock/node_modules/sinon/lib/sinon/util/core.js:78:29)
at Object.wrapMethod (node_modules/aws-sdk-mock/node_modules/sinon/lib/sinon/util/core.js:121:21)
at Object.stub (node_modules/aws-sdk-mock/node_modules/sinon/lib/sinon/stub.js:67:26)
at mockService (node_modules/aws-sdk-mock/index.js:67:27)
at Object.AWS.mock (node_modules/aws-sdk-mock/index.js:43:5)
at Context.<anonymous> (myModule.spec.js:14:9)
Thoughts?
Hey,
Node v6.9.1
AWS SDK v2.10.0
I'm trying to mock SES.sendEmail but the method isn't being mocked.
My test:
it('Should send an email if the email exists', async function () {
var updateTableSpy = sinon.spy();
mockAWS.mock('SES', 'sendEmail', updateTableSpy);
const result = await graphql(schema, emailSendQueryMutation('[email protected]'), {}, {});
const { userForgotPasswordEmailSend } = result.data;
userForgotPasswordEmailSend.sent.should.equal(true);
should.not.exist(result.errors);
// Assert on your Sinon spy as normal
console.log(updateTableSpy.calledOnce);
mockAWS.restore('SES', 'sendEmail');
});
This is calling this:
const UserForgotPasswordEmailSend = mutationWithClientMutationId({
name: 'UserForgotPasswordEmailSend',
inputFields: {
email: {type: new GraphQLNonNull(GraphQLString)}
},
outputFields: {
sent: { type: GraphQLBoolean }
},
mutateAndGetPayload: async ({email}, context) => {
let user = await UserModel.findOne({
where: { email }
});
if (!user) {
throw new Error('Email not found.');
}
let res = await sendForgotEmail(
await user.forgotPassword().save()
);
return {sent: true};
}
});
and sendForgotEmail is here:
import SES from 'aws-sdk/clients/ses';
import config from 'config';
import fs from 'fs';
import handlebars from 'handlebars';
import { toGlobalId } from 'graphql-relay';
const aws = config.aws;
const from = '[email protected]';
const layout = handlebars.compile(fs.readFileSync(__dirname + '/../../static/emails/transactional_layout.html.handlebar', 'UTF-8'));
const partialForgotEmail = handlebars.compile(fs.readFileSync(__dirname + '/../../static/emails/lost_password.html.handlebar', 'UTF-8'));
export function sendForgotEmail (user) {
let url = 'https://example/password/reset/' + user.password_reset_token;
let html = layout({
content: partialForgotEmail({
user, url
}),
title: 'Reset password'
});
return sendEmail(
'Reset password instructions',
html,
[user.email]
);
}
function sendEmail (title, html, emails) {
let ses = new SES({
accessKeyId: aws.accessKeyId,
secretAccessKey: aws.secretAccessKey,
region: aws.region,
});
return ses.sendEmail({
Source: from,
Destination: { ToAddresses: emails},
Message: {
Subject: {
Data: title
},
Body: {
Html: {
Data: html,
Charset: 'UTF-8'
}
}
}
}).promise();
}
console.log(updateTableSpy.calledOnce);
returns false
.
I don't know what I'm doing wrong, any idea?
Alex
I'm trying to mock DynamoDB.DocumentClient, I've made sure to mock the nested service like the example in the help, as well as made sure DocumentClient is initialized in the function being tested.
I keep getting an error:
ConfigError: Missing region in config
at Request.VALIDATE_REGION
The only noteworthy detail is that I'm assuming an IAM role in in AWS, which means no credentials are explicitly set in code (this works in AWS).
not sure if it's Sinon version issue or something else.
TypeError: Cannot read property 'restore' of undefined
at restoreMethod (C:\Projects\xxx\node_modules\aws-sdk-mock\index.js:158:45)
at restoreAllMethods (C:\Projects\xxx\node_modules\aws-sdk-mock\index.js:149:5)
at restoreService (C:\Projects\xxx\node_modules\aws-sdk-mock\index.js:139:3)
at restoreAllServices (C:\Projects\xxx\node_modules\aws-sdk-mock\index.js:131:5)
at Object.AWS.restore (C:\Projects\xxx\node_modules\aws-sdk-mock\index.js:116:5)
at Suite. (C:\Projects\xxx\test\test.spec.js:18:9)
at context.describe.context.context (C:\Projects\xxx\node_modules\mocha\lib\interfaces\bdd.js:47:10)
at Object. (C:\Projects\xxx\test\test.spec.js:2:1)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Module.require (module.js:353:17)
at require (internal/module.js:12:17)
at C:\Projects\xxx\node_modules\mocha\lib\mocha.js:219:27
at Array.forEach (native)
at Mocha.loadFiles (C:\Projects\xxx\node_modules\mocha\lib\mocha.js:216:14)
at Mocha.run (C:\Projects\xxx\node_modules\mocha\lib\mocha.js:468:10)
at Object. (C:\Projects\xxx\node_modules\mocha\bin_mocha:403:18)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Function.Module.runMain (module.js:441:10)
at startup (node.js:139:18)
at node.js:968:3
As a person who is
new
to the DWYL Org/Community ๐
I need to know how to contribute to the project effectively ๐ญ
so that I can start my journey towards Doing What I Love with my Life! โค๏ธ โ ๐
Markdown:
_**Please read** our_ [**contribution guide**](https://github.com/dwyl/contributing) (_thank you_!)
Note: these are line-separated but in the actual rendered page it's all one line.
see: https://github.com/dwyl/contributing/blob/master/CONTRIBUTING.md
I have this piece of production code:
exports.getObjectSignedUrl = (objectId) => {
const bucket = 'BUCKET_NAME';
const signedUrlExpireSeconds = 60 * 5;
const s3 = new AWS.S3({
params: {
ServerSideEncryption: 'AES256',
},
});
const url = s3.getSignedUrl('getObject', {
Bucket: bucket,
Key: objectId,
Expires: signedUrlExpireSeconds,
});
return url; // url is a string, not a promise
};
This is my unit test
describe('objects.getObjectSignedUrl', () => {
before(() => {
AWS.mock('S3', 'getSignedUrl', function (apiCallToSign, params, callback) {
callback(null, 'MY_SIGNED_URL');
});
});
it('Get signed url', () => {
const o = require('./moduleToTest');
const url = o.getObjectSignedUrl('OBJECT_ID'); // When s3.GetSignedUrl stubbed, returns Promise
return url === 'MY_SIGNED_URL';
});
after(() => {
AWS.restore();
});
});
The issue is - real s3.getSignedUrl() method returns a string, but when stubbed it returns a promise. What do I do about it?
I want to be able to get at the method stub so I can do stub.onCall()
but i'm unsure this is possible.
Use case:
I'm trying to mock the test for AWS.DynamoDB.DocumentClient().writeBatch()
. writeBatch will reply with UnprocessedItems
for any items which were throttled during write, and it is up to the client to retry them, So, a new call to writeBatch is required.
So, I need the first call to send some UnprocessedItems, and the second to have an empty UnprocessedItems.
(to further complicate things, I'm using promises...)
Any help is appreciated. I know this isn't necessarily an Issue, but maybe it results in an enhancement.
It seems your license here in your repository (GPLv3) doesn't match what your NPM metadata says (GPLv2). Which one is correct?
I'm not groking at all how to use aws-sdk-mock with AWS SDK's promise support. Can anyone provide a quick example? My code would look like:
var getPromise = s3.getObject(params).promise();
getPromise.then(function(data) {
// ...
});
What would my mock look like? Presumably there's a way to resolve(data)
or something along those lines from my spec so I can return whatever data I want to test against?
Bonus points if you can show me how to hook up that promise with chai-as-promised or a sinon expectation ...
Currently it is not possible to mock a service like DynamoDB.DocumentClient
because it isn't a top-level service under the aws-sdk
module. It would be great to include this functionality.
What do we think of matching the version number in this package/module to that of the AWS SDK we are mocking? (currently 2.3.18
)
I am trying to mock this S3 call:
module.exports.getSignedUrl = function (param) { return new Promise(function (fulfill, reject) { new aws.S3().getSignedUrl('getObject', param, function (err, res) { if (err) reject(err); else fulfill(res); }); }); }
but my attempt fails because the callback is undefined:
`
const param = undefined;
const expectedError = "Missing options for S3.getSignedUrl call";
awsMock.mock('S3', 'getSignedUrl', function (params, callback) {
return callback(expectedError);
});
const promise = stutils.aws.getSignedUrl(param);
return expect(promise)
.to.be.rejectedWith(expectedError)
.then(d => { awsMock.restore('S3', 'getSignedUrl'); });
`
Any ideas how to fix this?
Particularly useful with S3.getObject
. I'll gladly implement this and send a PR - but I'm not sure what API this should have on the test author's side. I guess at minimum it should be supported and just return an empty stream, then we can improve from there.
Hello,
it is possible to mock specific calls?
e.g:
Jonas
https://codecov.io/gh/dwyl/aws-sdk-mock/src/99fb51f3da657d593de7af523f5b6978c37fb518/index.js
Two questions:
console.log
?console.log
?Hoping I'm just doing something wrong.
Module:
const getThing = function getThing() {
var s3 = new AWS.S3();
return s3.getObject(params).promise().then(function(data) {
var thing = JSON.parse(data.Body.toString());
return thing;
})
.catch(function(s3_error) {
logger.error('Error getting thing: ' + s3_error);
s3_error.description = 'We are having problem connecting to our schema, try again in a bit';
throw s3_error;
});
};
Test with mocha:
describe('getSchema()', () => {
let init;
before(() => {
AWS.mock('S3', 'getObject', (params, callback) => {
const data = {};
data.Body = 'thing';
logger.info(data);
callback(null, data);
});
init = proxyquire('module', { 'aws-sdk': AWS });
});
it('Should return a valid object', () => {
return module.getThing().then((data) => {
data.should.be.an('object');
});
});
});
However this doesn't actually mock AWS, it actually goes and connects to my s3 gets the data from there. Any ideas?
Hi Gang,
I'm sure I'm missing something super obvious but I can't seem to get this module to work. I've distilled my test to the following example:
Step to reproduce
Install both the aws-sdk
and aws-sdk-mock
using npm.
Create a file called test.js
and insert the following code into it.
var AWS = require('aws-sdk-mock');
AWS.mock('SNS', 'publish', 'test-message');
console.log(AWS);
var sns = AWS.SNS();
sns.publish({}, function(err, data) {
if (err) console.log(err, err.stack);
console.log(data);
});
Run the command node test.js
.
Expected Response
A console dump of the entire AWS sdk and then the message 'test-message'.
Actual Response
An error (see below).
var sns = AWS.SNS();
^
TypeError: AWS.SNS is not a function
Note
console.log(AWS) returns:
{ setSDK: [Function],
mock: [Function],
restore: [Function],
Promise: [Function: Promise] }
What's going on? How do I get this example working?
If I mock the publish
function on the SNS
service, how can I check to see that the expected message was published? It doesn't look like the mock is returned or otherwise accessible in order to check.
I have a promise chain that calls two different aws functions sequentially:
var dynamo = new AWS.DynamoDB.DocumentClient();
dynamo.get(params).promise()
.then((data) => {
...
return dynamo.update(params).promise();
}).then(() => {
...
}).catch((err) => {
//I want to mock this error to get to here
});
In my tests I mock them as such:
AWS.mock('DynamoDB.DocumentClient', 'get', function (params, callback) {
callback(null, { Data : "data" });
});
AWS.mock('DynamoDB.DocumentClient', 'update', function (params, callback) {
callback({ message: "error" });
});
However, the second function is not mocked - the code calls the real AWS function and I never reach the commented section of my code. The tests/mocks previously worked when the code was written using just callbacks, but has stopped once we refactored to use promises.
Am I using aws-sdk-mock incorrectly, or is this a limitation of the package?
In #24 logic was introduced that forks the way a service method is mocked depending on whether or not a callback is provided.
The aws-sdk has always returned an AWS.Request object in response to a method call, regardless of whether or not you provided a callback. This object is an event emitter, in addition to providing a .promise
property and several other of its own methods.
Before #24, if I wanted to mock the request object, I would do something like:
AWS.mock('s3', 'putObject', function() {
var request = new events.EventEmitter();
// ... etc ...
return request;
});
... and I could use this to test logic like:
s3.putObject(parms)
.on('error', function(err) { })
.on('success', function() {} );
Now I can't do this -- once I call .putObject
without a callback I have no access to the replacement function without using the .promise
property.
This is kinda rambling, but my point is that you're now mocking the AWS.Request object, but only one of its properties, making it impossible for me to use this library to mock the AWS.Request object myself.
Hi,
I am getting an error whenever I try to mock a Dynamo DB query call since upgrading to 1.6.0. The error I am getting is this: TypeError: Cannot read property 'operations' of undefined.
I haven't tried other mocks except for S3 which looks to be working fine (getObject and listObjects) so I don't know if this limited to the DynamoDB mock or the error is also affecting other areas.
Is this also occurring on your end?
I think it would be useful to re-mock a method that has already been mocked. For example, in my use case, I am testing a REST API that wraps DynamoDB and for each resource endpoint I'd like to mock DynamoDB.getItem
slightly differently.
I'm trying to call AWS.setSDKInstance()
as instructed but got the error:
TypeError: AWS.setSDKInstance is not a function
I notice that in the latest version (1.6.1) that I got with npm install
, there is no such method in index.js
while it's there on Github. Did you forget to update the version number?
When trying to mock out the 'search' method of ClousDearchDomain we get an invalidEndpoint exception.
InvalidEndpoint: AWS.CloudSearchDomain requires an explicit `endpoint' configuration option.
How to trigger it:
var csd = new AWS.CloudSearchDomain({
endpoint: 'some endpoint',
region: 'eu-west-1'
});
awsMock.mock('CloudSearchDomain', 'search');
The moment you add the aws.mock part, the error gets triggered
Would it make sense to create a mock for the API gateway? If so, I wouldn't mind working on it.
I want to test my application in the s3.getObject correctly and incorrectly works well or not. But it always response with the first mock.
How can I test my application in different scenarios?
Here is the relevant part of my test suite:
describe('Geolocation cache', function () {
before(function () {
AWSMock.setSDK(path.resolve('./node_modules/aws-sdk'))
AWSMock.mock('S3', 'getObject', function (params, callback) {
return callback()
})
geoDataCache.setCacheDir(cacheDir)
})
it('Should download file from S3 when cache file is not present', function (done) {
const queryData = {
bucket: 'bucket',
key: 'inexistent-file.json'
}
geoDataCache.getFromCache(queryData)
.should.eventually.be.rejected
.then(function () {
return geoDataCache.getFresh(queryData)
})
.should.eventually.be.equal('{"a":1}')
.and.notify(done)
})
after(function () {
AWSMock.restore('S3', 'getObject')
})
})
And here is the relevant part of the SUT:
function getFresh(query) {
const bucket = query.bucket
const key = query.key
const S3 = new AWS.S3()
return new Promise(function (resolve, reject) {
S3.getObject({Bucket: bucket, Key: key}, function (err, data) {
if (err) {
return reject (err)
}
return resolve(data)
})
})
}
However, I'm getting the following error:
> ENOENT: Could not find API configuration s3-2006-03-01
It seems like mocking isn't working to overload config.
Hi there,
I'm trying to mock Cognito
AWS Service in one of the test for my authentication lambda function, here is the piece of code where I'm mocking the service, everything seems fine but in the lambda handler the real service is being called rather than the mocked one, so I'm not sure If I'm doing something wrong or there is a known bug.
I'm using mocha and chai along with lambda-tester
beforeEach(function (done) {
cognitoMock = AWS.mock('CognitoIdentity', 'getOpenIdTokenForDeveloperIdentity', (params, cb) => {
cb(null, {
IdentityId: '12345',
Token: 'abcd1234'
});
});
done();
});
it('fail: when password is invalid', (done) => {
LambdaTester(myLambda.handler)
.event({"body": "{\n \"name\": \"jyenes\",\n \"password\": \"invalid\"\n}"})
.expectFail( function( err ) {
expect( err.message ).to
.equal('Authentication failed');
})
.verify(done);
});
In the handler I'm calling this method getToken
from the handler after authenticate the user.
function getToken(username, cb) {
const param = {
IdentityPoolId: config.IDENTITY_POOL_ID,
Logins: {}
};
param.Logins[config.DEVELOPER_PROVIDER_NAME] = username;
cognitoidentity.getOpenIdTokenForDeveloperIdentity(param, (err, data) => {
if (err) cb(err);
else cb(null, data.IdentityId, data.Token);
});
}
Thanks in advance for your help and for your hard work.
Hi there,
TL;DR: Mock rejects on error even when a callback is used.
When trying to mock an S3 getObject
request to return an error message, Node is complaining about an unhandled promise rejection, despite all promises being handled accordingly and working correctly without the mock.
function doSomething(param) {
return new Promise(function(resolve, reject) {
// Get the S3 Service.
var s3 = new AWS.S3();
// Create a queue of promises to work with.
var queue = [];
// Loop through each file.
param.forEach(function(file) {
// Create a promise for each file to download.
queue.push(new Promise(function(_resolve, _reject) {
// Get the file
s3.getObject({
Bucket: '...',
Key: '...'
}, function(err, response) {
// If we have an error, siliently fail.
if (err) {
console.log(err);
return _resolve(false);
}
// Resolve with the result.
_resolve(response);
});
});
});
});
// Attempt to download all files.
Promise.all(queue).then(function(results) {
// Failed results are false - we'll strip out falsey
// values, leaving only those that were successful.
results = results.filter(el => el);
// If we don't have anything to continue with, we'll hard fail.
if (!results || results.length > 0) {
return reject('No results');
}
resolve();
}).catch(function() {
reject('Something bad happened');
});
}
And then running:
doSomething(['...']).then(function() {
throw new Error("Promise should be rejected!");
}).catch(function(err) {
expect(err).to.equal('No results');
});
So... The above code, without a mock works as expected. I'm passing it an invalid S3 key, resulting in the correct NoSuchKey
error being thrown:
{
code: 'NoSuchKey',
message: 'The specified key does not exist.'
}
However when mocking that error:
AWS.mock('S3', 'getObject', function(config, callback) {
callback({
code: 'NoSuchKey',
message: 'The specified key does not exist.'
});
});
Causes the following to appear in my console, despite all tests passing correctly:
(node:4503) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): [object Object]
Listening for unhandledRejection
results in the error object I'm passing from the mock.
process.on('unhandledRejection', (reason, promise) => {
console.log(reason);
});
Looking at the code for aws-sdk-mock
- despite me using a callback rather than promises, it's rejecting a promise instead of returning the error via the callback as per the actual AWS SDK.
Any thoughts? I didn't realise that AWS supported promises, so I can update my code but for those using callbacks, I imagine this is a bug?
Trying out basic use of tape and aws-sdk-mock but am not able to mock aws. I am initialling the AWS service in the function:
...
const AWS = require("aws-sdk");
AWS.config.region = "us-west-2";
...
exports.SNSPublish = (message, subject, topic) => {
console.log("sns_pub");
let sns = new AWS.SNS();
let publishParams = {
TopicArn: topic,
Subject: subject,
Message: JSON.stringify(message, null, 2)
};
sns.publish(publishParams, function(err, data) {
if (err) {
console.log(err.stack);
return;
}
});
};
my attempt to mock sns publish:
...
const AWS = require('aws-sdk-mock');
const targetServerjs = require("../server.js");
...
function lambdaSNSPublishTest() {
AWS.mock('SNS', 'publish', 'test-message');
var testTarget = targetServerjs;
var testEvent = Object.assign(mockEvent);
var testSNS = testEvent.Records[0].Sns;
var testSpec = Object.assign(testEvent);
test("SNSPublish() test", t => {
var output = testTarget.SNSPublish(testSNS.Message, testSNS.Subject, testSNS.TopicARN);
t.equals(output, testSpec);
t.end();
});
AWS.restore();
}
which fails over creds:
TimeoutError: Missing credentials in config
Seems straightforward, but I am at a loss.
I don't get mock s3.getSignedUrl('getObject', params);
. I tried it with nested. But getSignedUrl
is not a nested class.
What I tried so far:
beforeEach(function() {
let headObjectParams = {
Bucket: 'mockedBucket',
Key: testEvent.body.id
};
AWS.mock('S3', 'headObject', function(headObjectParams, callback) {
callback(null, {});
});
let getSignedUrlParams = {
Bucket: 'mockedBucket',
Key: testEvent.body.id,
Expires: 500
};
AWS.mock('S3', 'getSignedUrl', 'getObject', function(getSignedUrlParams, callback) {
callback(null, {
data: 'https://example.com'
});
});
});
Tried:
AWS.mock('S3', 'getSignedUrl', 'getObject',
AWS.mock('S3', 'getSignedUrl.getObject',
AWS.mock('S3.getSignedUrl', 'getObject'
where S3.getSignedUrl
was mocked before the headObject
.
AWS.mock('S3', 'headObject'
is working perfectly.
Link to method: http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getSignedUrl-property
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.