【发布时间】:2019-10-18 01:06:18
【问题描述】:
我正在为使用 aws-sdk 列出来自 s3 存储桶的所有文件的服务编写单元测试。 在函数内部,我实例化了 S3 类并使用 listObjectsV2 从 S3 存储桶中获取文件,在测试中我应该模拟这个函数以返回一个虚拟数据。
问题是我找不到模拟实例化类来覆盖函数的方法,我不想在参数中传递 S3 对象(依赖注入)
aws.服务:
listAllFiles = (bucket: string, documentsPath: string): Promise<ObjectList> => {
const params: S3.ListObjectsV2Request = {
Bucket: bucket,
EncodingType: 'url',
StartAfter: documentsPath
};
return this.listAllFilesCore(params);
}
private listAllFilesCore(params: S3.ListObjectsV2Request): Promise<ObjectList> {
return new Promise<ObjectList>((resolve, reject) => {
let result: ObjectList = []; const s3bucket = new S3(this.config);
s3bucket.listObjectsV2(params, (err, data) => {
if (err) {
logger.error(err.message);
logger.error(err.stack);
reject(err);
} else {
result = result.concat(data.Contents);
if (data.IsTruncated) {
logger.debug('get further list...');
this.listAllFilesCore(Object.assign(params, { ContinuationToken: data.NextContinuationToken }))
.then(r => {
result = result.concat(r);
resolve(result);
});
} else {
logger.debug(`get S3 Success from ${params.StartAfter}`);
resolve(result);
}
}
});
});
}
let awsService: any;
beforeAll(() => {
jest.mock('aws-sdk/clients/s3');
awsService = require('./aws.service').awsService;
});
it('listAllFiles from S3', () => {
const S3 = require('aws-sdk/clients/s3');
S3.listObjectsV2 = jest.fn((param: any,
callback?: (err: any, data: any) => void) => {
callback(undefined, data2);
});
我得到 TypeError: s3bucket.listObjectsV2 is not a function
【问题讨论】:
-
模拟的目的是帮助设计更好的代码。如果你不能模拟它,它需要重新设计。更何况在代码之后写测试对代码重构没有帮助(这是测试的目的之一),反而会阻碍它。
-
感谢您的回复,所以您确认此代码不可测试,我应该在参数中传递实例?
-
被测函数没有使用
this.config(除了创建S3类的实例),它也不知道怎么用。我肯定会注入一个S3对象而不是它的配置。 -
最后我改变了我的实现注入一个模拟版本的 S3 谢谢你的推荐
标签: node.js typescript jestjs