我在模拟模块时遇到了一个奇怪的问题,尤其是 waitForTableExists
模块中的 @aws-sdk/client-dynamodb
。在给定的测试用例中,由于某种原因,waitForTableExists
执行实际代码而不是模拟代码。但是,正确模拟了 DynamoDBClient
类。我不确定我哪里出错了。
dynamodb.ts
包含要测试的函数。为简洁起见,文件的其他部分未显示。
// other code not shown ...
async function ifIsActive<R>(
client: DynamoDBClient,
f: () => R,
): Promise<R | undefined> {
try {
await waitForTableExists(
{ client, maxWaitTime: 30 },
{ TableName: 'a-table-name' },
);
return f();
} catch (error) {
logger.error(error, 'Error in waitForTableExists()');
}
}
export async function getItem(
client: DynamoDBClient,
): Promise<Config | undefined> {
async function f() {
const command = new GetItemCommand(...);
try {
const { Item } = await client.send(command);
return Item;
} catch (error) {
logger.error(error, `An error occurred when trying to get an item`);
}
return undefined;
}
return await ifIsActive(client, f);
}
部分 dynamodb.spec.ts
如下所示。
beforeEach(() => {
jest.resetAllMocks();
jest.resetModuleRegistry();
});
// other describes test cases not shown ...
describe('getItem()', () => {
beforeEach(() => {
jest.mock('@aws-sdk/client-dynamodb');
});
test('existing item', async () => {
const { DynamoDBClient, waitForTableExists } = await import('@aws-sdk/client-dynamodb');
const waitForTableExistsMock = mocked(waitForTableExists);
waitForTableExistsMock.mockImplementation(async () => {
console.log('>>>>> waitForTableExists mock 1'); // this never happens
return { state: WaiterState.SUCCESS };
})
const DynamoDBClientMock = mocked(DynamoDBClient, true);
const sendMock = DynamoDBClientMock.prototype.send;
send.mockImplementation(() = > {
console.log(`>>>>> send mock 1`); // this is printed to console output
return {Table:{TableStatus:'ACTIVE'}};
})
const client = new DynamoDBClient({});
const item = await getItem(client, 'an-existing-id');
expect(send).toBeCalledTimes(1);
expect(waitForTableExistsMock).toBeCalledTimes(1);
// other expect ...
});
在@aws-sdk/client-dynamodb
中,函数waitForTableExists
如下。
export const waitForTableExists = async (
params: WaiterConfiguration<DynamoDBClient>,
input: DescribeTableCommandInput
): Promise<WaiterResult> => {
const serviceDefaults = { minDelay: 20, maxDelay: 120 };
return createWaiter({ ...serviceDefaults, ...params }, input, checkState);
};