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

单元测试Stub dynamodb-onetable遇OneTableArgError报错求助

解决Stub dynamodb-onetable时的OneTableArgError问题

问题根源

你Stub DataService.getData 的写法本身没问题,但DataService模块在被导入时就会执行顶部的Table实例化代码——测试环境下如果没有正确配置TableName变量,模块加载阶段就会触发「Missing Name Property」错误,和你是否Stub getData完全无关。

解决方案

方案一:重构为依赖注入(推荐,更易维护测试)

修改代码结构,将Table实例作为依赖传入DataService,避免模块加载时直接实例化Table:

  1. 修改DataService.ts
import { Table } from 'dynamodb-onetable';

export default class DataService {
  #empDetailModel;

  constructor(tableInstance: Table) {
    this.#empDetailModel = tableInstance.getModel('empDetail');
  }

  async getData(empId: string, type: string) {
    const params = { empId, type }; // 注意原代码中params写的是projectId,这里修正为empId
    const response = await this.#empDetailModel.find(params);
    logger.trace('response', { response });
    return response;
  }
}
  1. 修改lambda.ts
    在lambda层创建DataService实例并导出:
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
import Dynamo from 'dynamodb-onetable/Dynamo';
import { Table } from 'dynamodb-onetable';
import DataService from './path/to/DataService';

export const client = new Dynamo({
  client: new DynamoDBClient({ region: REGION }),
});

const workspaceTable = new Table({
  client,
  name: TableName,
  schema,
  logger: true,
  partial: false,
});

export const dataService = new DataService(workspaceTable);
  1. 修改getDetails.ts
    使用导出的DataService实例:
import { dataService } from '../lambda';

const dataDetails = await dataService.getData(
  empId,
  'EMPLOYEE-SAVEDATA'
);
  1. 测试代码编写
    测试时可以完全控制DataService的依赖,无需担心模块加载时的Table实例化错误:
import sinon from 'sinon';
import DataService from '../path/to/DataService';
import getDetails from '../path/to/getDetails';

describe('getDetails', () => {
  it('should return mock employee data', async () => {
    // 创建模拟的DataService实例
    const mockDataService = new DataService({} as any);
    // Stub getData方法返回预设数据
    const getDataStub = sinon.stub(mockDataService, 'getData').resolves({
      id: 'test-emp-123',
      name: 'Test Employee',
      type: 'EMPLOYEE-SAVEDATA'
    });

    // 此处需要替换getDetails中的dataService依赖为mock实例,可通过依赖注入或模块mock实现
    const result = await getDetails('test-emp-123', 'EMPLOYEE-SAVEDATA');

    sinon.assert.calledOnceWithExactly(getDataStub, 'test-emp-123', 'EMPLOYEE-SAVEDATA');
    expect(result).toEqual({
      id: 'test-emp-123',
      name: 'Test Employee',
      type: 'EMPLOYEE-SAVEDATA'
    });
  });
});

方案二:快速修复(不修改原有结构)

如果不想重构代码,可在测试文件最顶部提前mock Table类或设置环境变量:

  1. Mock Table类
import sinon from 'sinon';
import { Table } from 'dynamodb-onetable';

// 必须在导入DataService之前mock Table,避免模块加载时实例化真实Table
sinon.stub(Table.prototype, 'getModel').returns({
  find: sinon.stub().resolves({ /* 预设模拟数据 */ })
});

// 现在再导入相关依赖
import DataService from '../path/to/DataService';
import getDetails from '../path/to/getDetails';

describe('getDetails', () => {
  it('should return mock data', async () => {
    const getDataStub = sinon.stub(DataService, 'getData').resolves({
      id: 'test-emp-456',
      name: 'Mock Employee'
    });

    const result = await getDetails('test-emp-456', 'EMPLOYEE-SAVEDATA');

    sinon.assert.calledOnce(getDataStub);
    expect(result).toEqual({ id: 'test-emp-456', name: 'Mock Employee' });
  });
});
  1. 设置环境变量(辅助)
    如果是因为TableName未定义导致的错误,可在测试前赋值:
// 测试文件最顶部
process.env.TableName = 'mock-test-table';

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 01:21:05