使用jest模拟AWS.DynamoDB.DocumentClient的构造函数

sy5wg1nm  于 2022-12-08  发布在  Jest
关注(0)|答案(7)|浏览(192)

我有一个函数,看起来像这样:

function connect() {
   const secret = 'secret';
   const key = 'key';
   const region = 'region';
   const client = new AWS.DynamoDB({
      secret,
      key,
      region
   });'
   return new AWS.DynamoDB.DocumentClient({ service: client })
}

我想测试函数connect。我已经模拟了DynamoDB构造函数,如下所示:

// See https://stackoverflow.com/questions/47606545/mock-a-dependencys-constructor-jest
jest.mock('aws-sdk', () => {
  const DynamoDB = jest.fn().mockImplementation(() => {
    return {};
  });
  return {
    DynamoDB,
  };
});

然而,这意味着DocumentClient构造函数失败。我如何模仿它呢?

8aqjt8rx

8aqjt8rx1#

根据duxtinto上面的评论:
在我的例子中(如果我没有阅读的话,在OP的例子中),DynamoDB不是作为函数调用的,而是一个带有DocumentClient字段的对象,所以这对我来说是有效的:

jest.mock('aws-sdk', () => {
  return {
    DynamoDB: { // just an object, not a function
      DocumentClient: jest.fn(() => ({
        put: mockDynamoDbPut
      }))
    }
  }});
zpgglvta

zpgglvta2#

这对我很有效:

const mockDynamoDbPut = jest.fn().mockImplementation(() => {
  return {
    promise() {
      return Promise.resolve({});
    }
  };
});

jest.doMock('aws-sdk', () => {
  return {
    DynamoDB: jest.fn(() => ({
      DocumentClient: jest.fn(() => ({
        put: mockDynamoDbPut
      }))
    }))
  };
});

希望对你也有帮助。
此致!
大卫大卫大卫

zyfwsgd6

zyfwsgd63#

DocumentClient可能会调用一些client方法,因此只需定义这些方法存根即可。

import AWS from 'aws-sdk';

jest.mock('aws-sdk', () => {
  const DynamoDB = jest.fn().mockImplementation(() => {
    return {
      batchGetItem: jest.fn(),
    };
  });
  return {
    DynamoDB,
  };
});

// you could inspect the mock
console.log(new AWS.DynamoDB({ ... }));
ubbxdtey

ubbxdtey4#

下面是我在TypeScript中使用jest的方法:

// blabla.test.ts
import { DynamoDB } from 'aws-sdk';
import { ConsumerClass } from '../consumer-class';
import { DependencyConsumerClass } from '../dependency-consumer-class';

/*
* Inside consumerClassInstance.save() is calling this.dynamo.putItem({...}).promise();
*/
jest.mock('aws-sdk', () => {
    return {
        DynamoDB: jest.fn(() => {
            return {
                putItem: jest.fn(() => {
                    return {
                        promise: jest.fn(() => true)
                    };
                })
            };
        })
    };
});

test('sample test', async () => {
    const dependencyConsumerClass = new DependencyConsumerClass();
    const consumerClassInstance = new ConsumerClass(dependencyConsumerClass, new DynamoDB());
    
    const result = await consumerClassInstance.save();
    console.log(result);
});
icomxhvb

icomxhvb5#

Jest为运行测试提供DynamoDB集成。参见this document,查看3. Configure DynamoDB client

const {DocumentClient} = require('aws-sdk/clients/dynamodb');

const isTest = process.env.JEST_WORKER_ID;
const config = {
  convertEmptyValues: true,
  ...(isTest && {endpoint: 'localhost:8000', sslEnabled: false, region: 'local-env'})
};

const ddb = new DocumentClient(config);

我想您可以将DynamoDB客户机配置抽象(如果您还没有抽象)到它自己的模块文件中,并导出该客户机,以便在其他地方需要它,当Jest测试运行时,客户机将被配置为指向您按照Jest DynamoDB文档的其他步骤设置的模拟DynamoDB服务器/表。

p8h8hvxi

p8h8hvxi6#

对我来说,以下是行之有效的方法:

import AWS from "aws-sdk"
...
jest.spyOn(AWS.DynamoDB, "DocumentClient").mockReturnValue(mockedDocumentClient);

这里mockedDocumentClient是我的模拟对象,它伪造了DocumentClient的行为。我只包含了我将在它上面使用的方法。

9bfwbjaz

9bfwbjaz7#

在尝试投票最多的答案时,我试图模拟文档客户端,但没有成功。
我得到这个错误:TypeError: AWS.DynamoDB.DocumentClient is not a constructor
相反,我意识到我必须将DocumentClient模拟为一个类,而不是函数。
因此,考虑到这一点,以下是起作用的方法:

jest.mock(`aws-sdk`, () => {
    class mockDocumentClient {
        async put(config) {
            //TODO: your logic here
            return true;
        }
        async query(config) {
            // TODO: your logic here
            return true;
        }
    }
    return {
        DynamoDB: {
            DocumentClient: mockDocumentClient,
    }};
});

相关问题