使用 jest 模拟 AWS.DynamoDB.DocumentClient 的构造函数
Posted
技术标签:
【中文标题】使用 jest 模拟 AWS.DynamoDB.DocumentClient 的构造函数【英文标题】:Mock the constructor for AWS.DynamoDB.DocumentClient using jest 【发布时间】:2020-01-08 16:36:56 【问题描述】:我有一个看起来像这样的函数:
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://***.com/questions/47606545/mock-a-dependencys-constructor-jest
jest.mock('aws-sdk', () =>
const DynamoDB = jest.fn().mockImplementation(() =>
return ;
);
return
DynamoDB,
;
);
但是,这意味着DocumentClient
构造函数失败。我该如何模拟呢?
【问题讨论】:
【参考方案1】: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 服务器/表。
【讨论】:
很高兴知道我们不必编写自己的帮助程序来运行集成测试(就像我一直在做的那样),我宁愿不使用本地发电机服务器单元测试。我认为如果使用 ts-jest,我们可以只使用 jest.mock('aws-sdk') 因为 aws-sdk 现在附带打字稿定义。【参考方案2】:基于上述 duxtinto 的评论:
在我的情况下(如果我没看错的话,在 OP 的情况下),DynamoDB 不是作为函数调用的,而是一个带有 DocumentClient 字段的对象,所以这对我有用:
jest.mock('aws-sdk', () =>
return
DynamoDB: // just an object, not a function
DocumentClient: jest.fn(() => (
put: mockDynamoDbPut
))
);
【讨论】:
【参考方案3】:在 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);
);
【讨论】:
【参考方案4】:这对我有用:
const mockDynamoDbPut = jest.fn().mockImplementation(() =>
return
promise()
return Promise.resolve();
;
);
jest.doMock('aws-sdk', () =>
return
DynamoDB: jest.fn(() => (
DocumentClient: jest.fn(() => (
put: mockDynamoDbPut
))
))
;
);
希望对你也有帮助。
问候,
大卫。
【讨论】:
这给了我错误ConfigError: Missing region in config
。任何想法将不胜感激!
当这种情况发生在我身上时,通常与模拟无法以某种方式或在错误的位置工作有关。这意味着 DocumentClient 尝试连接到数据库实例。
在我的情况下(如果我没看错的话,在 OP 的情况下),DynamoDB 不是作为函数调用的,而是一个带有 DocumentClient 字段的对象,所以这对我有用:` jest.mock('aws-sdk', () => return DynamoDB: // 只是一个对象,而不是一个函数 DocumentClient: jest.fn(() => ( put:模拟DynamoDbPut )) ); `【参考方案5】:
DocumentClient
可能会调用一些client
方法,因此只需定义这些方法存根即可。例如,DocumentClient
将在您的代码中使用 batchGetItem
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( ... ));
【讨论】:
以上是关于使用 jest 模拟 AWS.DynamoDB.DocumentClient 的构造函数的主要内容,如果未能解决你的问题,请参考以下文章
使用 jest.mock('axios') 时如何模拟拦截器?