测试节点表达端点和存根第 3 方 api 调用
testing node express endpoint and stub 3rd party api call
我有一个这样的快递应用程序:
server.js
const postsController = require('./controllers/posts_controller.js')
module.exports = app = express()
app.get('posts', postsController.index)
posts_controller.js
const post = require('./post')()
module.exports = {
index: (req, res) => {
post.getAll().then((posts) => {
res.status(200).send(posts)
}, (error) => {
res.status(400).send('text')
})
}
}
post.js
module.exports = () => {
const thirdPartyApi = require('third_party_api')
return {
get: () => {
// do some stuff
return thirdPartyApi.get().then((resp) => {
// do some more stuff
return Promise.resolve(resp)
})
}
}
}
spec/posts_controller_spec.js
const app = require('../server')
const request = require('supertest')
describe('GET /posts', () => {
it('should return a collection of posts', () => {
request(app)
.get('/posts')
.end((_err, resp) => {
expect(resp.status).toEqual(200)
})
})
})
我的目标是去掉 thirdPartyApi.get()
。我通过将此行添加到 posts_controller_spec:
来尝试使用 proxyquire
proxyquire('../posts_controller', {third_party_api: {
get: () => { console.log('stubbed out get method'); }
})
这不起作用,因为 server.js 文件是再次需要 third_party_api 的文件。
我可以做这样的事情来测试控制器:
const postsController = proxyquire('../posts_controller', {third_party_api: {
get: () => { console.log('stubbed out get method'); }
})
postsController.index(req, res)
第二种策略感觉不对,因为现在我必须对 req
和 res
进行存根,现在我要绕过实际的 app
实例。
有没有一种简单的方法可以做到这一点,使用 proxyquire 或其他方式?
我意识到发生了什么,proxyquire 实际上并没有搞砸这里。
文件 post.js
导出一个函数,所以当 posts_controller.js
requires() post.js 文件时,它会执行该函数并再次计算 third_party_api
的要求存根被清除了。
这是此处描述的 "runtimeGlobal" 场景:https://www.npmjs.com/package/proxyquire#globally-override-require-during-module-runtime
解决方案是修复 post.js
,使其不导出函数:
const thirdPartyApi = require('third_party_api')
return {
get: () => {
// do some stuff
return thirdPartyApi.get().then((resp) => {
// do some more stuff
return Promise.resolve(resp)
})
}
}
现在,只要在应用程序初始化之前发生这种情况,
proxyquire('../posts_controller', {third_party_api: {
get: () => { console.log('stubbed out get method'); }
})
然后在 post 控制器中需要的 third_party_api 模块在加载时进行评估,并按预期进行缓存。
我有一个这样的快递应用程序:
server.js
const postsController = require('./controllers/posts_controller.js')
module.exports = app = express()
app.get('posts', postsController.index)
posts_controller.js
const post = require('./post')()
module.exports = {
index: (req, res) => {
post.getAll().then((posts) => {
res.status(200).send(posts)
}, (error) => {
res.status(400).send('text')
})
}
}
post.js
module.exports = () => {
const thirdPartyApi = require('third_party_api')
return {
get: () => {
// do some stuff
return thirdPartyApi.get().then((resp) => {
// do some more stuff
return Promise.resolve(resp)
})
}
}
}
spec/posts_controller_spec.js
const app = require('../server')
const request = require('supertest')
describe('GET /posts', () => {
it('should return a collection of posts', () => {
request(app)
.get('/posts')
.end((_err, resp) => {
expect(resp.status).toEqual(200)
})
})
})
我的目标是去掉 thirdPartyApi.get()
。我通过将此行添加到 posts_controller_spec:
proxyquire
proxyquire('../posts_controller', {third_party_api: {
get: () => { console.log('stubbed out get method'); }
})
这不起作用,因为 server.js 文件是再次需要 third_party_api 的文件。
我可以做这样的事情来测试控制器:
const postsController = proxyquire('../posts_controller', {third_party_api: {
get: () => { console.log('stubbed out get method'); }
})
postsController.index(req, res)
第二种策略感觉不对,因为现在我必须对 req
和 res
进行存根,现在我要绕过实际的 app
实例。
有没有一种简单的方法可以做到这一点,使用 proxyquire 或其他方式?
我意识到发生了什么,proxyquire 实际上并没有搞砸这里。
文件 post.js
导出一个函数,所以当 posts_controller.js
requires() post.js 文件时,它会执行该函数并再次计算 third_party_api
的要求存根被清除了。
这是此处描述的 "runtimeGlobal" 场景:https://www.npmjs.com/package/proxyquire#globally-override-require-during-module-runtime
解决方案是修复 post.js
,使其不导出函数:
const thirdPartyApi = require('third_party_api')
return {
get: () => {
// do some stuff
return thirdPartyApi.get().then((resp) => {
// do some more stuff
return Promise.resolve(resp)
})
}
}
现在,只要在应用程序初始化之前发生这种情况,
proxyquire('../posts_controller', {third_party_api: {
get: () => { console.log('stubbed out get method'); }
})
然后在 post 控制器中需要的 third_party_api 模块在加载时进行评估,并按预期进行缓存。