使用lambda / node代码运行Jest测试时遇到问题。当我运行index.js时,Axios get可以正常工作。
这是我的index.js
const sslRootCAs = require('ssl-root-cas/latest')
const util = require('util')
exports.handler = async function (event) {
const axios = require('axios');
//const user = process.env.user;
//const pw = process.env.pw;
const user = '';
const pw = '';
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
return axios.get('https://url', {
auth: {username: user, password: pw}, rejectUnauthorized: false
})
.then(res => {
return {
statusCode: 200,
body: res.data
};
})
.catch(err => {
return {
statusCode: 500,
body: JSON.stringify(err)
};
});
}
这是我的index.test.js
const lambda = require("./index");
const axios = require("axios");
const mockAdapter = require("axios-mock-adapter");
// afterEach(() => {
// mockAxios.reset();
// });
it("test get - this will pass", async () => {
let mock = new mockAdapter(axios, {delayResponse: 1000});
mock.onGet().reply({
status: 200,
data: {
expand: 'schema,names',
startAt: 0,
maxResults: 50,
total: 2
}
});
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
var event = {Key: "12345"};
const result = await lambda.handler(event);
console.log(result);
expect(result).toMatchObject({ status: 200, body: "test" });
mock.reset();
});
我已经使用index.test.js尝试了多种方法。我什至剪掉了所有的模拟,并且正在测试以查看get是否会工作。它不是。运行npm test时出现“无法验证第一个证书”的信息。
当我执行节点index.js时,代码不会引发该错误。我怀疑开玩笑是否为该错误或Axios提供了某种内置处理程序?
任何想法都很棒。
谢谢, 蒂姆
答案 0 :(得分:1)
我将从移动开始
const axios = require('axios');
超出函数调用范围。我怀疑运行测试时正在发生的事情是这样的:
Axios具有一个称为create()的强大功能,它可以创建一个实例(请参阅:https://github.com/axios/axios)。我通常会为要在应用程序中使用的所有端点创建一个单独的实例,然后从单独的文件中导出这些端点。这使得重用逻辑和模拟端点变得容易。例如,您可以创建一个仅包含以下代码的文件 api.js :
const axios = require('axios')
export default () => axios.create({baseURL: 'https://url', timeout: 5000})
然后在您的index.js / handler
中import api from './api.js' // or const api = require('./api.js')
...
exports.handler = async function (event) {
....
return api.get('/', { // make sure not to repeat the baseURL
auth: {username: user, password: pw}, rejectUnauthorized: false
})
此外,如果您使用的是异步等待,则可以只删除.then和.catch。这是处理诺言的两种不同方法。最好选择一个并坚持下去。
那更干净,更容易阅读。
然后,在您从中调用lambda的任何函数中(例如测试),您都可以执行以下操作:
const result = await lambda.handler(event);
expect(result).toMatchObject({ status: 200, body: "test" });
对于代码中的其他位置,您可以通过将所有内容包装在try / catch中来处理在调用函数中设置响应代码的情况,如下所示:
try {
const result = await lambda.handler(event);
res.json(result.body);
catch (e) {
res.status(500).send({error: e})
}
然后您应该通过执行以下操作将模拟适配器附加到您创建的axios实例:
const lambda = require("./index");
const api = require("./api");
const mockAdapter = require("axios-mock-adapter");
it("test get - this will pass", async () => {
let mock = new mockAdapter(api, {delayResponse: 1000});
mock.onGet('/').reply({ // make sure to specify the route your're mocking
status: 200,
data: {
expand: 'schema,names',
startAt: 0,
maxResults: 50,
total: 2
}
});
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
var event = {Key: "12345"};
const result = await lambda.handler(event);
console.log(result);
expect(result).toMatchObject({ status: 200, body: "test" });
mock.reset();
});