开玩笑-模拟承诺的SQS通话

问题描述 投票:0回答:1

假设我有一个带有方法QueueClasssend,该方法获取一些数据作为参数然后将其发送到SQS队列。我想编写2个测试:一种用于测试MessageBody和QueueUrl键是否传递了预期值的程序。如果发生错误,则会引发异常。

要测试的方法如下:我的send方法:

async send(data) {
  return SQS.sendMessage({
    MessageBody: JSON.stringify(data),
    QueueUrl: 'queue_url_here',
  })
    .promise()
    .catch((error) => {
      // Throw exception ...
    });
}

我对该方法的测试:

const aws = require('aws-sdk');

jest.mock('aws-sdk', () => {
  const SQSMocked = {
    sendMessage: jest.fn().mockReturnThis(),
    promise: jest.fn(),
  };

  return {
    SQS: jest.fn(() => SQSMocked),
  };
});

sqs = new aws.SQS();

test('my test', async () => {
  const data = {};
  await QueueClass.send(data);

  expect(sqs.sendMessage).toHaveBeenCalledWith({
    MessageBody: JSON.stringify(data),
    QueueUrl: 'queue_url_here',
  });
});

该测试给我以下错误:TypeError: Cannot read property 'catch' of undefined我确实尝试将catch: jest.fn()添加到SQSMocked对象中,与我使用promise完全相同,但是不断出现相同的错误。

事实是,当我更改要尝试测试的方法时,它使用try-catch block而不是.promise().catch()

async send(data) {
  try {
    return SQS.sendMessage({
      MessageBody: JSON.stringify(data),
      QueueUrl: 'queue_url_here',
    });
  } catch (error) {
    // Throw exception ...
  }
}

我的测试通过了,所以让我认为这不一定是正确模拟SQS的问题。

[任何想法,为什么在使用.promise().catch()时我的测试失败?另外,我该如何测试队列抛出错误的情况?我希望能够做这样的事情:

  await expect(sqs.sendMessage)
    .resolves
    .toEqual(...);

OR

  await expect(sqs.sendMessage)
    .rejects
    .toThrowError(new Error('Some error thrown.'));
unit-testing promise mocking jestjs amazon-sqs
1个回答
0
投票

promise被存根并返回undefined,这就是为什么它不返回可以链接的承诺的原因。

由于顾名思义,它有望返回承诺,因此应为:

promise: jest.fn().mockRejectedValue(new Error(...));

[await expect(sqs.sendMessage)对其进行测试没有意义,因为它会测试您刚刚编写的代码。

可能应该是:

await expect(QueueClass.send(data)).rejects.toThrowError(...);

这可能是一个错误:

async send(data) {
  try {
    return SQS.sendMessage(...);
  } catch (error) {
    // Throw exception ...
  }
}

[try..catch无法捕获来自async返回的异步错误,也没有将sendMessage返回值转换为Promise。

应该是:

async send(data) {
  try {
    return await SQS.sendMessage(...).promise();
  } catch (error) {
    // Throw exception ...
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.