You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

函数内调用函数方法及Jest中Mock DynamoDB Put Promise报错解决

解决Jest中Mock DynamoDB put().promise()的问题

错误原因

你当前的mock代码让put方法直接返回了car对象,但原代码中put(params)之后会调用.promise(),而car对象并没有promise方法,因此抛出TypeError: this.getDbClient(...).put(...).promise is not a function错误。

另外,你的测试代码还有一个问题:createCar函数没有返回值,所以const result = await DatabaseHandler.createCar(car)得到的是undefined,expect(result).toEqual(car)会断言失败,需要先修正createCar函数。

步骤1:修正createCar函数

在createCar中添加返回值,让测试断言有意义:

static createCar = async (car: Car) => {
  const params: DocumentClient.PutItemInput = {
    TableName: this.tableName,
    Item: car
  }
  await this.getDbClient().put(params).promise();
  return car; // 添加此行返回传入的car对象
}

步骤2:正确Mock put().promise()

推荐使用jest.spyOn来mock静态方法getDbClient,避免修改全局的documentClient影响其他测试:

const car: Car = {
  id: 892421
};    

it('#DatabaseHandler should create car', async () => {
  // 定义mock的put方法,返回带有promise方法的对象
  const mockPut = jest.fn().mockReturnValue({
    promise: jest.fn().mockResolvedValue(car) // promise方法返回resolved的Promise
  });

  // Mock getDbClient,让它返回包含mockPut的假client
  jest.spyOn(DatabaseHandler, 'getDbClient').mockReturnValue({
    put: mockPut
  } as unknown as DynamoDB.DocumentClient);

  const result = await DatabaseHandler.createCar(car);
  
  // 断言返回值正确
  expect(result).toEqual(car);
  // 断言put方法被正确调用,参数符合预期
  expect(mockPut).toHaveBeenCalledWith({
    TableName: 'cars',
    Item: car
  });
  // 断言promise方法被调用
  expect(mockPut.mock.results[0].value.promise).toHaveBeenCalled();
});

另一种方式:直接Mock put方法

如果你不想mock整个getDbClient,可以直接修改put方法,但记得测试后恢复原方法:

it('#DatabaseHandler should create car', async () => {
  const originalPut = DatabaseHandler.getDbClient().put;
  
  try {
    // Mock put方法,返回带有promise的对象
    DatabaseHandler.getDbClient().put = jest.fn().mockReturnValue({
      promise: jest.fn().mockResolvedValue(car)
    });

    const result = await DatabaseHandler.createCar(car);
    
    expect(result).toEqual(car);
    expect(DatabaseHandler.getDbClient().put).toHaveBeenCalledWith({
      TableName: 'cars',
      Item: car
    });
  } finally {
    // 恢复原put方法,避免影响其他测试
    DatabaseHandler.getDbClient().put = originalPut;
  }
});

内容的提问来源于stack exchange,提问作者Tiago Silva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 09:05:23