使用 Jest 模拟 AWS SES

Bor*_*uhh 6 unit-testing node.js jestjs aws-sdk aws-sdk-nodejs

我尝试在 Jest 中模拟 AWS SES,但仍然收到此超时错误:

Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.Error:
Run Code Online (Sandbox Code Playgroud)

我已经删除了不相关且经验证可以正常工作的代码。下面是使用 SES 的代码:

import SES from 'aws-sdk/clients/ses';

try {
    /** Initialize SES Class */
    const ses = new SES({ apiVersion: '2010-12-01' });

    await ses.sendTemplatedEmail(sesEmailParams).promise();
} catch(err) {
    return next(internalErrorMessage);
}
Run Code Online (Sandbox Code Playgroud)

这是使用 SES 的测试:

import AWS from 'aws-sdk';

test('Should error when ses.sendTemplatedEmail.promise() fails', async (done) => {
    const fakeSesPromise = {
      promise: jest
        .fn()
        .mockImplementationOnce(() => Promise.reject(new Error('This is an SES error'))),
    };

    const fakeSes = {
      sendTemplatedEmail: () => {
        return fakeSesPromise;
      },
    };

    AWS.SES = jest.fn(() => fakeSes);

    await user.forgotPassword(mockRequest, mockResponse, mockNext);

    expect(fakeSesPromise).toHaveBeenCalledTimes(1);
    expect(mockNext).toHaveBeenCalledWith(internalErrorMessage);

    done();
});
Run Code Online (Sandbox Code Playgroud)

我尝试了其他一些建议的方法,但都得到了相同的结果。aws-sdk我假设它与如何使用该函数有关.promise()

任何帮助将非常感激!

更新#1:

@slideshowp2 的以下解决方案有效,但会抛出此 Typescript 错误:

Property 'mockRejectedValueOnce' does not exist on type '() => Promise<PromiseResult<SendTemplatedEmailResponse, AWSError>>'
Run Code Online (Sandbox Code Playgroud)

对于这一行:

mockSes.sendTemplatedEmail().promise.mockRejectedValueOnce(new Error('This is an SES error'));
Run Code Online (Sandbox Code Playgroud)

要使其工作,只需更改此行:

const mockSes = new mockSES();
Run Code Online (Sandbox Code Playgroud)

到:

const mockSes = (new SES() as unknown) as { sendTemplatedEmail: jest.Mock; promise: jest.Mock };
Run Code Online (Sandbox Code Playgroud)

sli*_*wp2 7

这是一个使用jest.mock(moduleName,factory,options)、模拟aws-sdk/clients/ses模块、SES类及其方法的单元测试解决方案。

\n\n

例如

\n\n

user.js:

\n\n
import SES from \'aws-sdk/clients/ses\';\n\nconst internalErrorMessage = \'internalErrorMessage\';\n\nexport const user = {\n  async forgotPassword(req, res, next) {\n    const sesEmailParams = {\n      Source: \'Sender Name <sender@recipient.com>\',\n      Destination: {\n        ToAddresses: [],\n      },\n      Template: \'tpl\',\n      TemplateData: \'data\',\n    };\n    try {\n      const ses = new SES({ apiVersion: \'2010-12-01\' });\n      await ses.sendTemplatedEmail(sesEmailParams).promise();\n    } catch (err) {\n      return next(internalErrorMessage);\n    }\n  },\n};\n
Run Code Online (Sandbox Code Playgroud)\n\n

user.test.js:

\n\n
import MockSES from \'aws-sdk/clients/ses\';\nimport { user } from \'./user\';\n\njest.mock(\'aws-sdk/clients/ses\', () => {\n  const mSES = {\n    sendTemplatedEmail: jest.fn().mockReturnThis(),\n    promise: jest.fn(),\n  };\n  return jest.fn(() => mSES);\n});\n\ndescribe(\'61491519\', () => {\n  test(\'Should error when ses.sendTemplatedEmail.promise() fails\', async () => {\n    const mSes = new MockSES();\n    const mError = new Error(\'This is an SES error\');\n    mSes.sendTemplatedEmail().promise.mockRejectedValueOnce(mError);\n    const mockRequest = {};\n    const mockResponse = {};\n    const mockNext = jest.fn();\n    await user.forgotPassword(mockRequest, mockResponse, mockNext);\n\n    expect(MockSES).toBeCalledWith({ apiVersion: \'2010-12-01\' });\n    expect(mSes.sendTemplatedEmail).toBeCalledWith({\n      Source: \'Sender Name <sender@recipient.com>\',\n      Destination: {\n        ToAddresses: [],\n      },\n      Template: \'tpl\',\n      TemplateData: \'data\',\n    });\n    expect(mSes.sendTemplatedEmail().promise).toBeCalledTimes(1);\n    expect(mockNext).toHaveBeenCalledWith(\'internalErrorMessage\');\n  });\n});\n
Run Code Online (Sandbox Code Playgroud)\n\n

100%覆盖率的单元测试结果:

\n\n
 PASS  stackoverflow/61491519/user.test.js (10.071s)\n  61491519\n    \xe2\x9c\x93 Should error when ses.sendTemplatedEmail.promise() fails (6ms)\n\n----------|---------|----------|---------|---------|-------------------\nFile      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s \n----------|---------|----------|---------|---------|-------------------\nAll files |     100 |      100 |     100 |     100 |                   \n user.js  |     100 |      100 |     100 |     100 |                   \n----------|---------|----------|---------|---------|-------------------\nTest Suites: 1 passed, 1 total\nTests:       1 passed, 1 total\nSnapshots:   0 total\nTime:        12.115s\n
Run Code Online (Sandbox Code Playgroud)\n