我有一个基于 express
的应用程序在 node.js 0.12.2
上运行,它使用来自 的
根据特定存储桶是否存在返回 JSON 响应。 s3.headBucket
方法>aws-sdk 2.1.22
我一直在努力用 sinon 直接停止对 s3.headBucket
的调用。我设法通过创建一个 s3wrapper 模块来解决这个问题,该模块只需要 aws-sdk
并实例化并返回 s3
变量,但是,我相信这可以不使用包装器模块就可以完成,而是可以直接用 sinon stub ,有人能指出我正确的方向吗?
下面是当前工作的代码(带有包装器模块 s3wrapper.js
,我想删除它并处理我的 status_router_spec.js
文件中的 stub )。换句话说,我希望能够调用 s3.headBucket({Bucket: 'whatever' ...
而不是 s3wrapper.headBucket({Bucket: ' ...
并能够用我自己的响应来阻止此 s3.headBucket
调用。
status_router_spec.js
var chai = require('chai'),
sinon = require('sinon'),
request = require('request'),
myHelper = require('../request_helper')
var expect = chai.expect
var s3wrapper = require('../../helpers/s3wrapper')
describe('My router', function () {
describe('checking the service status', function () {
var headBucketStub
beforeEach(function () {
headBucketStub = sinon.stub(s3wrapper, 'headBucket')
})
afterEach(function () {
s3wrapper.headBucket.restore()
})
describe('when no errors are returned', function () {
it('returns healthy response', function (done) {
// pass null to represent no errors
headBucketStub.yields(null)
request.get(myHelper.appUrl('/status'), function (err, resp, body) {
if (err) { done(err) }
expect(JSON.parse(body)).to.deep.eql({
healthy: true,
message: 'success'
})
done()
})
})
})
})
})
s3wrapper.js
var AWS = require('aws-sdk')
var s3 = new AWS.S3()
module.exports = s3
status_router.js
var Router = require('express').Router
var s3wrapper = require('../helpers/s3wrapper.js')
var router = new Router()
function statusHandler (req, res) {
s3wrapper.headBucket({Bucket: 'some-bucket-id'}, function (err) {
if (err) {
return res.json({ healthy: false, message: err })
} else {
return res.json({ healthy: true, message: 'success' })
}
})
}
router.get(/^\/status\/?$/, statusHandler)
module.exports = router
最佳答案
为了 @ippomakunochi 的利益而回答这个问题,他要求跟进回复。
我们最终使用了 rewire直接在 s3 库上设置 stub 。例如,我们使用以下代码对 s3 库的 getObject
调用进行了 stub :
s3stub = { getObject: sinon.stub(), listObjects: sinon.stub() }
revert = s3.__set__('s3', s3stub)
完整代码如下:
../../../build/app/helpers/s3
var AWS = require('aws-sdk');
var s3 = new AWS.S3();
module.exports = {
get: function get(options, callback) {
var requestOptions = { Bucket: module.exports.bucket(), Key: options.productId + '.json' };
s3.getObject(requestOptions, function (err, data) {
if (err) { // handle err }
try {
var productData = JSON.parse(data.Body);
} catch (e) {
// handle error
}
return callback(null, productData);
});
}
}
}
test/unit/app/helpers/s3_spec.js
var AWS = require('aws-sdk')
var chai = require('chai')
var sinon = require('sinon')
var sinonChai = require('sinon-chai')
var chaiSubset = require('chai-subset')
var rewire = require('rewire')
var s3 = rewire('../../../build/app/helpers/s3')
chai.use(chaiSubset)
chai.use(sinonChai)
var expect = chai.expect
describe('S3', function () {
var s3stub, revert
beforeEach(function () {
s3stub = { getObject: sinon.stub(), listObjects: sinon.stub() }
revert = s3.__set__('s3', s3stub)
})
afterEach(function () {
revert()
})
describe('#get', function () {
context('when no errors are returned by s3', function () {
it('returns a product', function (done) {
var productResponse = helper.fixture.body('product.json')
s3stub.getObject.yields(null, productResponse)
s3.get({ productId: '1234' }, function (err, res) {
expect(err).to.not.exist
expect(res).to.containSubset({name: 'long sleeve shirt', 'retailer_code': 'retailer-1'})
done()
})
})
})
context('when s3 returns a NoSuchKey error', function () {
it('returns a NotFoundError', function (done) {
var s3Error = AWS.util.error(new Error(), { name: 'NoSuchKey' })
s3stub.getObject.yields(s3Error)
s3.get({ productId: '1234' }, function (err) {
expect(err.message).to.eql('1234 is not found in s3')
expect(err.output.statusCode).to.eql(404)
done()
})
})
})
})
关于node.js 在请求规范中用 sinon stub AWS S3 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29937045/