typescriptjestjsamazon-dynamodb

Jest DynamoDB Test Failing


I am attempting to write a jest unit test involving using DynamoDB. It seems the afterAll condition is executing too fast which is making my integ test failing since it fails to get the already deleted items.

My DynamoDB table has an event source of S3 which gets triggered when there is a new object in the S3 bucket.

const s3 = new S3Client();
const ddb = new DynamoDBClient();
const sqs = new SQSClient();
const SECONDS = 1000;

const testUtil = new TestUtils(ddb, s3, sqs);

jest.useFakeTimers({ legacyFakeTimers: true });

describe("Single item upload workflow", () => {
  const offeringId = "S-#########";
  const bucketKey = "integ_test.csv";
  const keys = { pk: TYPE, sk: offeringId };
  const testItem = [
    {...},
  ];

  beforeAll(async () => {
    const csv = unparse(testItem);
    await testUtil.putItemInS3(bucketKey, csv);
  }, 10 * SECONDS);

    afterAll(async () => {
      await testUtil.deleteObjectFromS3(bucketKey);
      await testUtil.deleteItemFromDdb(keys);
    }, 10 * SECONDS);

  it(
    "mocks setTimeout correctly",
    () => {
      setTimeout(() => {}, 10000);
      expect(setTimeout).toHaveBeenCalled();
    },
    10 * SECONDS
  );

  it(
    "Should appear in DynamoDB table",
    async () => {
      expect.assertions(1);
      setTimeout(() => {}, 10000);
      const response = await testUtil.getItemFromDdb(keys);
      const result = {...},
      };

      expect(response.Item).toMatchObject(result);
    },
    10 * SECONDS
  );

I tried using a variety of jest timers but seems to be failing. It passes when I comment out the afterAll block since it doesn't delete the item but I want to properly clean up after all tests has ran.


Solution

  • Found my problem, I wasn't awaiting my setTimeout call in my async tests

    const timeout = (duration: number) =>
      new Promise((resolve) => setTimeout(resolve, duration));
    
      it("Should appear in DynamoDB table", async () => {
        expect.assertions(1);
    
        await timeout(2 * SECONDS);
    
        const response = await testUtil.getItemFromDdb(keys);
        const result = {...};
    
        expect(response.Item).toMatchObject(result);
    
        await testUtil.deleteObjectFromS3(bucketKey);
        await testUtil.deleteItemFromDdb(keys);
      });