【问题标题】:How to mock an instantiated class inside a function without dependency injection如何在没有依赖注入的情况下模拟函数内的实例化类
【发布时间】: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


【解决方案1】:

您可以使用jest.mock(moduleName, factory?) 方法手动模拟导入的模块。这是文档:https://jestjs.io/docs/en/manual-mocks

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-08
    • 2018-07-12
    • 1970-01-01
    • 2023-01-12
    • 2022-12-17
    • 1970-01-01
    相关资源
    最近更新 更多