我有一个像这样的快递应用程序:
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)
})
}
}
}
规格/ 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()
。我尝试使用proxyquire
将此行添加到posts_controller_spec:
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或其他方式吗?
答案 0 :(得分:2)
我意识到发生了什么,代理查询实际上并没有弄乱这里。
文件post.js
导出一个函数,所以当posts_controller.js
需要()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模块在加载时进行评估,并按预期缓存。