我的问题是关于在Node.js中使用promise和事件发射器进行单元测试.如果重要的话,我正在使用茉莉花框架.
下面的代码使用Node.js的https模块将请求发送到API.该API将返回JSON.来自API的JSON是以下代码中的“ rawData”变量.
我想对该功能返回JSON(而不是JavaScript对象)进行单元测试.
我已经尝试了几种方法来对该功能的这一方面进行单元测试:
1)我尝试监视Promise构造函数,以使其返回假函数,该函数仅返回JSON字符串.
2)我尝试监视Node.js中EventEmitters的.on(‘eventType’,callback)函数,以伪造返回JSON的函数.
我的问题是:以上两种方法是否可能和/或建议实现我的目标?有没有其他方法可以从我的单元测试目标中隔离http请求和发出事件?我是否需要重写此功能以简化单元测试?
const https = require('https');
function getJSON() {
return new Promise((resolve, reject) => {
const request = https.get(someConfig);
request.on('response', resolve);
})
.then(msg => {
return new Promise((resolve, reject) => {
let rawData = '';
msg.on('data', chunk => { rawData += chunk });
msg.on('end', () => {
resolve(rawData);
});
});
})
.then(json => {
JSON.parse(json);
return json;
})
}
解决方法:
我要说的是,您需要对代码进行一些重构以使其更具可测试性.
当我为功能编写单元测试时,请牢记以下几点
>您无需测试内置模块或库模块,因为它们已经过良好的测试.
>始终将您的功能重构为非常具体的职责.
在您的示例中实现这两者,我将在一个服务模块中分离服务器调用,该服务模块的唯一责任是采用url(以及配置(如果有))进行服务器调用.
现在,当您这样做时,会获得两个好处
1.您有一段可重用的代码,您现在可以使用它来进行其他服务器调用(也使您的代码更简洁)
>由于它是一个模块,您现在可以为该模块编写单独的测试,并负责检查是否从使用该模块的当前模块进行服务器调用.
现在,要在getJSON函数中进行测试的所有事情就是将服务模块spyOn并使用tohaveBeenCalledWith并检查数据是否已正确解析.您可以对服务进行模拟以返回所需的数据.
1拨打服务电话
所以测试toHaveBeenCalledWith
2将其解析为JSON
因此测试有效/无效的JSON
也测试失败
//no need to test whether https is working properly
//its already tested
const https = require('https');
const service = require("./pathToservice");
function getJSON() {
return service.get(somConfig)
.then(json => {
JSON.parse(json);
return json;
})
}
//its cleaner now
//plus testable