【发布时间】:2015-07-08 08:15:37
【问题描述】:
我有一个基于express 的应用程序在node.js 0.12.2 上运行,它使用aws-sdk 2.1.22 中的s3.headBucket 方法返回JSON 响应,具体取决于特定存储桶是否存在。
我一直在努力使用 sinon 直接将对 s3.headBucket 的呼叫拒之门外。我已经设法通过创建一个 s3wrapper 模块来解决这个问题,该模块只需要aws-sdk 并实例化并返回s3 变量,但是,我确信这可以在不使用包装器模块的情况下完成,而是可以被存根直接用sinon,有人能指出我正确的方向吗?
下面是当前工作的代码(带有包装模块s3wrapper.js,我想删除并处理我的status_router_spec.js 文件中的存根)。换句话说,我希望能够调用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
【问题讨论】:
-
s3wrapper.headBucket的存根对我来说看起来不错(尽管您可以删除引用并直接调用s3wrapper.headBucketStub.yields(null)),但是request.get呢?这也需要被存根,并且回调产生了。 -
我在测试中明确使用
headBucketStub.yields(null)的原因是因为我实际上有几个不同的测试,我希望headBucket方法为每个测试返回不同的值。至于request.get,我实际上也想要这个,因为这是一个请求测试,所以我正在向一个为测试设置的服务器实例发送一个实际请求。经过进一步调查,如果我从status_router模块中导出s3变量,我就可以摆脱s3wrapper,尽管这并不是真正的改进 -
我遇到了同样的问题,但即使我使用包装器也不起作用。
-
@kunde 尝试发布您的代码,也许有人可以提供一些帮助。我相信我难以取消调用的原因是因为在请求规范中,您需要启动一个服务器,如果您要直接调用它,看起来我正在对 S3 库进行存根,但是一旦它通过服务器,请求到达未存根版本。创建 S3 包装器允许我将 S3 调用存根,并且我还切换到使用 supertest 模块来运行我的服务器。
-
@adamc 原来我使用错误的包装器。我只在测试中需要包装器,但在我需要测试的模块中不需要。在分析了情况之后,您可以存根包装的 s3 实例是有道理的,因为没有包装器,您正在尝试存根不同的实例。如果没有包装器,我不知道该怎么做,但这样对我来说很好。
标签: node.js amazon-s3 sinon aws-sdk