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

如何对DynamoDB query操作的分页功能进行Mock与单元测试

问题原因

你当前测试代码的问题在于DynamoDB query的stub是固定返回全量数据,不会响应你接口传入的排序、分页参数(对应DynamoDB原生参数ScanIndexForward、Limit、ExclusiveStartKey),因此无法验证分页排序逻辑是否正确。

解决方案1:使用条件化Stub模拟DynamoDB行为

你可以将固定返回的stub修改为根据调用参数动态返回对应分页排序后的数据,示例修改如下:

test('should paginate backward and forward', async () => {
  const allTestItems = [
    {
      convertedUrl: 'https://xxxx.awssensei.tk/ddddd',
      createdAt: '2021-11-04T05:50:14.180Z',
      originalUrl: 'https://aws.com',
      updatedAt: '2021-11-04T05:58:12.659Z',
    },
    {
      convertedUrl: 'https://xxxx.awssensei.tk/bbbbb',
      createdAt: '2021-11-04T05:50:43.818Z',
      originalUrl: 'https://fb.com',
      updatedAt: '2021-11-04T05:57:42.704Z',
    },
    {
      convertedUrl: 'https://xxx.awssensei.tk/eeeee',
      createdAt: '2021-11-04T05:50:55.121Z',
      originalUrl: 'https://google.com',
      updatedAt: '2021-11-04T05:58:21.141Z',
    },
    {
      convertedUrl: 'https://xxxx.awssensei.tk/aaaaa',
      createdAt: '2021-11-04T05:51:06.603Z',
      originalUrl: 'https://instagram.com',
      updatedAt: '2021-11-04T05:57:14.750Z',
    },
  ];

  sandbox
    .stub(AWS.DynamoDB.DocumentClient.prototype, 'query')
    .callsFake(async (params) => {
      // 处理排序逻辑
      let processedItems = [...allTestItems];
      if (params.ScanIndexForward === false) {
        processedItems = processedItems.reverse();
      }
      // 处理分页逻辑
      const pageLimit = params.Limit || processedItems.length;
      let startIndex = 0;
      if (params.ExclusiveStartKey) {
        // 此处根据你的表排序键调整匹配逻辑,示例用createdAt作为排序键
        startIndex = processedItems.findIndex(item => item.createdAt === params.ExclusiveStartKey.createdAt) + 1;
      }
      const resultItems = processedItems.slice(startIndex, startIndex + pageLimit);
      // 生成下一页游标
      const lastEvaluatedKey = startIndex + pageLimit < processedItems.length
        ? { createdAt: resultItems[resultItems.length - 1].createdAt }
        : undefined;

      return {
        Items: resultItems,
        LastEvaluatedKey: lastEvaluatedKey
      };
    });

  const app = require('../app');
  // 测试正序全量返回
  const response = await request(app)
    .get('/users/auth-user/urls?sort_by=createdAt')
    .set('Authorization', `Bearer ${token}`);
  expect(response.body.history.length).toBe(4);

  // 追加分页测试逻辑:每页2条,测试第一页返回
  const page1Res = await request(app)
    .get('/users/auth-user/urls?sort_by=createdAt&page_size=2')
    .set('Authorization', `Bearer ${token}`);
  expect(page1Res.body.history.length).toBe(2);
  expect(page1Res.body.next_cursor).toBeDefined();

  // 测试第二页返回
  const page2Res = await request(app)
    .get(`/users/auth-user/urls?sort_by=createdAt&page_size=2&cursor=${page1Res.body.next_cursor}`)
    .set('Authorization', `Bearer ${token}`);
  expect(page2Res.body.history.length).toBe(2);
  expect(page2Res.body.next_cursor).toBeUndefined();
});

解决方案2:使用本地DynamoDB做集成测试

如果需要更贴近生产环境的测试效果,可以直接使用本地DynamoDB实例:

  • 本地启动DynamoDB Docker容器,将SDK请求端点指向本地实例
  • 测试前置逻辑中创建对应表、批量写入预设测试数据
  • 测试完成后清空表数据即可,不需要修改业务代码的query逻辑

内容的提问来源于stack exchange,提问作者Jatin Mehrotra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 06:36:02