Sha*_*llu 2 javascript unit-testing mocking node.js jestjs
我有一个使用本机 https.request 使用 Azure Function 内的 Node Js 构建的外部 POST API,一切正常。现在我正在尝试构建单元测试用例,并对模拟 Request 方法感到震惊。
回调响应具有“on”功能,需要根据“data”或“end”值进行模拟。
我收到此错误TypeError: res.on is not a function
下面是代码。有什么建议 !
索引.js
'use strict';
const https = require('https')
const fs = require('fs')
const path = require('path')
module.exports = function(context, postData) {
//Accessing Certificate and Passing along with Request Options for SSL Handshake
var ca_path = path.join(__dirname, 'my_cert.cer');
https.globalAgent.options.ca = fs.readFileSync(ca_path).toString()
.split(/-----END CERTIFICATE-----\n?/)
// may include an extra empty string at the end
.filter(function(cert) { return cert !== ''; })
// effectively split after delimiter by adding it back
.map(function(cert) { return cert + '-----END CERTIFICATE-----\n'; });
let auth = 'Basic ' + Buffer.from(process.env.username + ':' + process.env.pwd).toString('base64');
let post_option = {
host: process.env.host,
path: process.env.path,
method: 'POST',
port: process.env.port,
headers: {
'Content-Type': 'application/json',
'Authorization': auth,
'X-Correlation-ID': JSON.parse(postData).correlationId
}
};
return new Promise(function(resolve, reject) {
var req = https.request(post_option, function(res) {
// accumulate data
var body = [];
res.on('data', function(chunk) { //here is the type error
body.push(chunk);
});
// resolve on end
res.on('end', function() {
context.log("API status: " + res.statusCode);
if (res.statusCode == 200) {
try {
body = JSON.parse(Buffer.concat(body).toString());
context.log("API Success: ");
} catch (err) {
reject(err);
}
resolve(body);
} else if (res.statusCode == 401) {
let errJson = {};
context.log("API authentication error...");
let err = new Error();
errJson["errorCode"] = res.statusCode;
errJson["errorMessage"] = res.statusMessage;
errJson["errorDescription"] = res.statusMessage;
err = errJson;
return reject(err);
} else {
body = JSON.parse(Buffer.concat(body).toString());
context.log("API error...", body);
let err = new Error();
if (body.error != null && body.error != undefined) {
err = body.error;
} else {
let errJson = {};
errJson["errorCode"] = res.statusCode;
errJson["errorMessage"] = res.statusMessage;
errJson["errorDescription"] = res.statusMessage;
err = errJson;
}
return reject(err);
}
});
});
// reject on request error
req.on('error', function(err) {
context.log("API Generic error...", err);
let err = new Error();
let errJson = {};
if (err.message && err.message.indexOf("ENOTFOUND") >= 0)
errJson["errorCode"] = 404;
else
errJson["errorCode"] = 500;
errJson["errorMessage"] = err.message;
errJson["errorDescription"] = err.message;
err = errJson;
reject(err);
});
if (postData) {
req.write(postData);
}
req.end();
});
}
Run Code Online (Sandbox Code Playgroud)
索引.test.js
var https = require('https');
jest.mock('https', () => ({
...jest.requireActual('https'), // import and retain the original functionalities
request: (post_option, cb) => cb('res')({
on: jest.fn()
}),
on: jest.fn(),
write: jest.fn(),
end: jest.fn()
}));
/*
jest.mock('https', () => ({
...jest.requireActual('https'), // import and retain the original functionalities
request: (post_option, cb) => cb('res')({
on: (data, cb) => cb('data')
}),
on: jest.fn(),
write: jest.fn(),
end: jest.fn()
}));
*/
/* jest.mock('https', () => ({
...jest.requireActual('https'), // import and retain the original functionalities
request: (post_option, cb) => cb(jest.fn(() => ({
on: jest.fn()
}))),
on: jest.fn(),
write: jest.fn(),
end: jest.fn()
}));
*/
/* jest.mock('https', () => ({
...jest.requireActual('https'), // import and retain the original functionalities
request: (post_option, cb) => cb({
on: jest.fn()
})
}));
*/
Run Code Online (Sandbox Code Playgroud)
尝试了不同的方法来为“on”功能创建模拟,但没有成功。
经过3个小时的实验,我终于能够模拟“res”的“on”功能了。
cb 实际上应该设置为一个需要 2 个参数的函数
这是模拟语法。
let apiResponseBody = `{
"status": "Dummy Request sent to API"
}`;
var https = require('https');
jest.mock('https', () => ({
...jest.requireActual('https'), // import and retain the original functionalities
request: (post_option, cb) => cb({
on: (data, cb) => cb(Buffer.from(apiResponseBody, 'utf8')),
statusCode: 200,
statusMessage: 'API Success'
}),
on: jest.fn(),
write: jest.fn(),
end: jest.fn()
}));
Run Code Online (Sandbox Code Playgroud)