Skip to content

Commit 20df34c

Browse files
committed
first
0 parents  commit 20df34c

File tree

7 files changed

+486
-0
lines changed

7 files changed

+486
-0
lines changed

.eslintrc

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"rules": {
3+
"indent": [2, 2],
4+
"quotes": [2, "single"],
5+
"quote-props": [2, "as-needed"],
6+
"no-console": [1],
7+
"semi": [2, "always"],
8+
"space-before-function-paren": [2, "never"],
9+
"object-curly-spacing": [2, "always"],
10+
"array-bracket-spacing": [2, "never"],
11+
"comma-spacing": [2, { "before": false, "after": true }],
12+
"key-spacing": [2, { "beforeColon": false, "afterColon": true }]
13+
},
14+
"env": {
15+
"node": true,
16+
"es6": true
17+
},
18+
"globals": {
19+
"process": true,
20+
"module": true,
21+
"require": true
22+
},
23+
"extends": "eslint:recommended"
24+
}

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules/
2+
.nyc_output/
3+
coverage/

index.js

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
var events = require('events');
2+
var sinon = require('sinon');
3+
var _AWS = require('aws-sdk');
4+
var traverse = require('traverse');
5+
6+
module.exports = _AWS;
7+
module.exports.stub = stubMethod;
8+
9+
/**
10+
* Replaces a single AWS service method with a stub.
11+
*
12+
* @param {string} service - the name of the AWS service. Can include `.` for
13+
* nested services, e.g. `'DynamoDB.DocumentClient'`.
14+
* @param {string} method - the name of the service method to stub.
15+
* @param {function} [replacement] - if specified, this function will be called
16+
* when the service method stub is invoked. `this` in the context of the function
17+
* will provide a reference to stubbed AWS.Request and AWS.Response objects to
18+
* simulate more advanced aws-sdk-js usage patterns.
19+
* @returns {object} stub - [a sinon stub](http://sinonjs.org/docs/#stubs).
20+
*/
21+
function stubMethod(service, method, replacement) {
22+
if (!isStubbed(service)) stubService(service);
23+
if (!replacement) return sinon.stub(getService(service).prototype, method);
24+
25+
return sinon.stub(getService(service).prototype, method, function(params, callback) {
26+
var _this = { request: stubRequest(), response: stubResponse() };
27+
replacement.call(_this, params, callback);
28+
return _this.request;
29+
});
30+
}
31+
32+
function isStubbed(service) {
33+
return getService(service).isSinonProxy;
34+
}
35+
36+
function getService(name) {
37+
return traverse(_AWS).get(name.split('.'));
38+
}
39+
40+
function setService(name, fn) {
41+
traverse(_AWS).set(name.split('.'), fn);
42+
}
43+
44+
function stubService(service) {
45+
var Original = getService(service);
46+
var client = new Original();
47+
48+
function FakeService(config) { Object.assign(this, new Original(config)); }
49+
FakeService.prototype = Object.assign({}, client.__proto__);
50+
51+
var spy = sinon.spy(FakeService);
52+
spy.restore = function() { setService(service, Original); };
53+
54+
setService(service, spy);
55+
}
56+
57+
function stubRequest() {
58+
var req = new events.EventEmitter();
59+
var stubbed = sinon.createStubInstance(_AWS.Request);
60+
for (var method in req.__proto__) delete stubbed[method];
61+
return Object.assign(req, stubbed);
62+
}
63+
64+
function stubResponse() {
65+
var req = new events.EventEmitter();
66+
var stubbed = sinon.createStubInstance(_AWS.Response);
67+
for (var method in req.__proto__) delete stubbed[method];
68+
return Object.assign(req, stubbed);
69+
}

package.json

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
{
2+
"name": "@mapbox/mock-aws-sdk-js",
3+
"version": "0.0.1",
4+
"description": "Create stubbed aws-sdk-js clients for testing purposes",
5+
"main": "index.js",
6+
"engines": {
7+
"node": ">4.0.0"
8+
},
9+
"scripts": {
10+
"pretest": "eslint index.js test",
11+
"test": "nyc tape test/*.test.js",
12+
"coverage": "nyc --reporter html tape test/*.test.js && opener coverage/index.html"
13+
},
14+
"repository": {
15+
"type": "git",
16+
"url": "git+https://github.com/mapbox/mock-aws-sdk-js.git"
17+
},
18+
"keywords": [
19+
"aws",
20+
"mock",
21+
"sinon",
22+
"testing"
23+
],
24+
"author": "Mapbox",
25+
"license": "ISC",
26+
"bugs": {
27+
"url": "https://github.com/mapbox/mock-aws-sdk-js/issues"
28+
},
29+
"homepage": "https://github.com/mapbox/mock-aws-sdk-js#readme",
30+
"peerDependencies": {
31+
"aws-sdk": "^2.5.0"
32+
},
33+
"dependencies": {
34+
"sinon": "^1.17.5",
35+
"traverse": "^0.6.6"
36+
},
37+
"devDependencies": {
38+
"eslint": "^3.5.0",
39+
"nyc": "^8.1.0",
40+
"opener": "^1.4.2",
41+
"tape": "^4.6.0"
42+
}
43+
}

readme.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# @mapbox/mock-aws-sdk-js
2+
3+
A library that provides sinon-style stubs for aws-sdk-js service methods for use in testing.
4+
5+
### Goals
6+
7+
- allow tests to make assertions about both service client configuration (e.g. region) and method arguments
8+
- enable tests for application logic with varied usage of `AWS.Request` object methods
9+
10+
### Basic usage
11+
12+
Your application, `app.js`:
13+
14+
```js
15+
var AWS = require('aws-sdk');
16+
17+
module.exports = function(callback) {
18+
// It is important that aws-sdk clients be defined in a function, and not
19+
// as module-level variables.
20+
var s3 = new AWS.S3({ region: 'eu-west-1' });
21+
s3.getObject({ Bucket: 'bucket', Key: 'key' }, function(err, data) {
22+
if (err) return callback(err);
23+
callback(null, data.Body.toString());
24+
});
25+
}
26+
```
27+
28+
Your test script:
29+
30+
```js
31+
var test = require('tape');
32+
var app = require('./app');
33+
var AWS = require('@mapbox/mock-aws-sdk-js');
34+
35+
test('gets S3 object', function(assert) {
36+
var data = { Body: new Buffer('hello world') };
37+
var expected = { Bucket: 'bucket', Key: 'key' };
38+
39+
var getObject = AWS.stub('S3', 'getObject', function(params, callback) {
40+
callback(null, data);
41+
});
42+
43+
app(function(err, data) {
44+
assert.ifError(err, 'success');
45+
assert.equal(data, 'hello world');
46+
47+
assert.equal(AWS.S3.callCount, 1, 'one s3 client created');
48+
assert.ok(AWS.S3.calledWithExactly({ region }), 's3 client created for the correct region');
49+
50+
assert.equal(getObject.callCount, 1, 'called s3.getObject once');
51+
assert.ok(getObject.calledWith(expected), 'called s3.getObject with expected params');
52+
53+
AWS.S3.restore();
54+
assert.end();
55+
});
56+
});
57+
```
58+
59+
Read all about [how to use sinon stubs here](http://sinonjs.org/docs/#stubs).
60+
61+
### More examples
62+
63+
`test/test-app.js` represents a module that makes the same basic S3.getObject request in several different ways. `test/index.test.js` then contains a number of examples for how you might choose to write tests for the module.

0 commit comments

Comments
 (0)