我正在嘗試撰寫一個單元測驗 (jest) 來測驗服務的執行。目前,測驗超時,我很肯定這與我創建讀取流有關。我是否正確地嘲笑了 s3.getObject.createReadStream()?
處理程式
const XLSX = require("xlsx");
const AWS = require("aws-sdk");
import { Pool } from "pg";
class Service {
client: any;
workbook: any = "";
constructor(client) {
this.workbook = "";
this.client = client;
}
async createWorkbookFromS3(filePath: string, id: string) {
const fileLocation = id filePath;
const params = {
Bucket: "bucket",
Key: fileLocation,
};
function getBufferFromS3(callback) {
const buffers = [];
const s3 = new AWS.S3();
const stream = s3.getObject(params).createReadStream();
stream.on("data", (data) => buffers.push(data));
stream.on("end", () => callback(null, Buffer.concat(buffers)));
stream.on("error", (error) => callback(error));
}
function getBufferFromS3Promise() {
return new Promise((resolve, reject) => {
getBufferFromS3((error, s3buffer) => {
if (error) {
return reject(error)
};
return resolve(s3buffer);
});
});
}
try {
const buffer = await getBufferFromS3Promise();
this.workbook = XLSX.read(buffer);
} catch (e) {
if (e) {
this.client.release()
console.error(e);
throw new Error("Unable to read the xlsx from S3");
}
}
}
}
const decoder = async (event: any) => {
const id: string = event.body["id"];
const filePath = `${id}.xlsx`;
try {
switch (event.path) {
case "/vsiDecoder/draft":
try {
const filePath: string = event.body["filePath"];
const dbCredentials = {"user":"postgres","password":"password","host":"awsconnectihoststring","port": "0000" ,"database":"db"}
const pool = new Pool(JSON.parse(dbCredentials['SecretString']));
const client = await pool.connect();
const vsiObj = new Service(client);
await vsiObj.createWorkbookFromS3(filePath, id);
vsiObj.client.release()
pool.end();
} catch (e) {
throw new Error(e)
}
return {
statusCode: 200,
message: "The document has been successfully drafted.",
};
default:
return {
message: "Bad request",
statusCode: 400,
};
}
} catch (e) {
console.log(e)
return{
statusCode: 400,
message: e.message,
}
}
};
module.exports = {Service, decoder }
handler.test.ts
const decoder = require('./handler.ts')
import { Pool } from 'pg';
const mockgetObject = {
createReadStream: jest.fn(() => {
return {
on: jest.fn()
}
})
}
const mockS3Instance = {
putObject: jest.fn().mockReturnThis(),
promise: jest.fn().mockReturnThis(),
catch: jest.fn(),
getObject: jest.fn(() => mockgetObject)
}
jest.mock('aws-sdk', () => {
return {
S3: jest.fn(() => mockS3Instance),
}
});
jest.mock('pg', () => {
const mClient = {
connect: jest.fn().mockReturnThis(),
query: jest.fn().mockReturnThis(),
end: jest.fn().mockReturnThis(),
release: jest.fn().mockReturnThis(),
};
return { Pool: jest.fn(() => mClient) };
});
describe('Service Test', () => {
let client;
beforeEach(() => {
client = new Pool();
jest.setTimeout(30000);
});
afterEach(() => {
jest.clearAllMocks();
});
it('should executre decoder', async () => {
const id = 'id';
const filePath = 'filePath'
const service = new decoder.Service(client);
await service.createWorkbookFromS3(id, filePath)
const events = { 'body': { 'id': '1234', "path": "/decoder/draft", "vsiFilePath": "path" } };
const response = '{"statusCode":200,"message":"The document has been succesfully drafted."}';
expect((await decoder.decoder(events)).body).toEqual(response);
})
})
錯誤:
Service Test ? should executre decoder
: Timeout - Async callback was not invoked within the 30000 ms timeout specified by jest.setTimeout.Timeout - Async callback was not invoked within the 30000 ms timeout specified by jest.setTimeout.Error:
感謝任何幫助!我確實相信我成功地模擬了 createReadStream 但如果有一種方法來模擬 getBufferFromS3Promise 是可以接受的。
uj5u.com熱心網友回復:
在您的createReadStream模擬中,該on函式沒有實作。但是,在 for 的代碼中getBufferFromS3(callback),該on函式負責設定執行回呼函式的事件處理程式,這是getBufferFromS3Promise決議或拒絕來自 Promise 的地方。因為這個承諾永遠不會被解決或拒絕,所以你的異步測驗代碼永遠不會完成。
您需要實作以on某種方式執行事件處理程式回呼的函式的模擬。如果您只是測驗成功案例,您可以只在其中同步執行處理程式,on因為 'end' 事件恰好在 'error' 事件之前連接。更好的方法可能是通過on保存處理程式來模擬事件發射器,并向triggerEvent流模擬添加一個函式,該函式允許您在測驗中強制觸發不同的流事件。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/360725.html
標籤:javascript 打字稿 亚马逊网络服务 单元测试 玩笑
