[英]How to mock required files in Node.js?
我正在尝试模拟节点模块,以便它将返回模拟数据。 但是在我的测试中,它仍在进行实际调用。 考虑以下代码:
const makeRequestStructure = require('./modules/makeRequestStructure.js').makeRequestStructure
const normalizeFinalResponse = require('./modules/normalizeFinalResponse.js').normalizeFinalResponse
const doARequest = require('./modules/doARequest.js').doARequest
exports.addPost = (event) => {
const requestStructure = makeRequestStructure('POST', '/posts')
const requestPostData = {
title: event.body.title,
content: event.body.content
}
return doARequest(requestStructure, requestPostData).then((res) => {
const finalResponse = normalizeFinalResponse(200, res)
return finalResponse
}).catch((err) => {
const finalResponse = normalizeFinalResponse(400, err)
return finalResponse
})
}
我有以下测试文件:
const mock = require('mock-require')
const sinon = require('sinon')
const expect = require('chai').expect
const addPost = require('../addPost.js')
describe('the addPost API call', () => {
beforeEach(() => {
mock('../modules/doARequest', { doARequest: function() {
return Promise.resolve({})
}})
});
it('Returns with a statusCode of 200', () => {
const event = { body: { title: 'Lorem ipsum', content: 'Lorem ipsum dolor sit amet' } }
const expectedReturn = { id: 20000000000000 }
return addPost.addPost(event).then((res) => {
expect(res.body.message).to.eql(expectedReturn)
})
});
})
该测试正在对https://jsonplaceholder.typicode.com/posts
进行实际调用,并返回{ id: 101 }
。 但是我希望它返回{ id: 20000000000000 }
。 我试图使用Nock模拟请求。 但是,主机名是在.env
文件中定义的,并且可能会有所不同,具体取决于运行脚本的服务器。
doARequest.js
文件如下所示:
const https = require('https')
module.exports.doARequest = function (params, postData) {
return new Promise((resolve, reject) => {
const req = https.request(params, (res) => {
let body = []
res.on('data', (chunk) => {
body.push(chunk)
})
res.on('end', () => {
try {
body = JSON.parse(Buffer.concat(body).toString())
} catch (e) {
reject(e)
}
resolve(body)
})
})
req.on('error', (err) => {
reject(err)
})
if (postData) {
req.write(JSON.stringify(postData))
}
req.end()
})
}
我在这里做错了什么? 任何帮助将不胜感激。
CommonJS模块产生单例导出对象。 导入模块后,将不对其进行评估。 mock(...)
不会产生任何影响,因为在导入addPost
时已对原始的doARequest
模块进行了评估。
mock-require
提供了一种重新评估模块的方法 。 addPost
不应导入测试文件的顶部。 相反,应该将其导入使用它的测试中:
const addPost = mock.reRequire('../addPost.js');
作为使用reRequire模块的替代estus解决方案,您可以使用“依赖注入”。
问题是,你直接取决于doARequest.js
在-module addPost.js
,从而使其难以讥笑它的行为。 这是依赖注入派上用场的地方,因为您只需在单元测试中传递一个模拟的doARequest-module即可:
// addPost.js
exports.addPost = (event, doARequest) => {
const requestStructure = makeRequestStructure('POST', '/posts')
const requestPostData = {
title: event.body.title,
content: event.body.content
}
return doARequest(requestStructure, requestPostData).then((res) => {
const finalResponse = normalizeFinalResponse(200, res)
return finalResponse
}).catch((err) => {
const finalResponse = normalizeFinalResponse(400, err)
return finalResponse
})
}
// addPost.test.js
describe('the addPost API call', () => {
it('Returns with a statusCode of 200', () => {
const mockedDoARequest = () => Promise.resolve({ "whateverResponseYouLike": "12345" });
const event = { body: { title: 'Lorem ipsum', content: 'Lorem ipsum dolor sit amet' } }
const expectedReturn = { id: 20000000000000 }
return addPost.addPost(event, mockedDoARequest).then((res) => {
expect(res.body.message).to.eql(expectedReturn)
})
});
})
您将在其他任何地方传递真实模块,即
const doARequest = require('./modules/doARequest.js').doARequest
...
return addPost.addPost(event, doARequest).then(...)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.