如何模拟使用 AWS 资源的打字稿服务和功能?

How to mock typescript services and functions that use AWS resources?

我有一个 Typescript 后端结构,我想为所有功能创建单元测试。我正在使用 JESTaws-skd-mock 来模拟 AWS。我尝试了一些东西,但似乎我做的事情不对。

我有这项服务,我从 ParamterStore 获取参数 (amazon.service.ts):

import * as AWS from "aws-sdk";

export class AmazonService {

  parameterStore: AWS.SSM;

  constructor() {
    this.parameterStore = new AWS.SSM();
  }

  async getParam(param) {
    let self = this;
    console.log('IN getPARAM', param);
    return new Promise(function(resolve, reject){
      self.parameterStore.getParameter({
        Name: param,
        WithDecryption: true
      }, function (err, data) {
        if (err) {
          console.log('Error ', err);
          return resolve({Error: 'ParameterNotFound'})
        }
        console.log('RES ', data.Parameter.Value);
        return resolve(data.Parameter.Value)
      })
    })
  }

}

然后,我模拟整个 amazon.service 文件,我模拟 SSM.getParameter 并在我的测试文件 (amazon.service.spect.ts):

import * as AWSMock from "aws-sdk-mock";
import * as AWS from "aws-sdk";
import {AmazonService} from "./amazon.service";


jest.mock('./amazon.service');

describe('amazon service mock', () => {
  let amazonService: AmazonService;

  it('should get Parameter from Parameter Store', async () => {
    const ssmGetParameterPromise = jest.fn().mockReturnValue({
      promise: jest.fn().mockResolvedValue({
        Parameter: {
          Name: 'NAME',
          Type: 'SecureString',
          Value: 'VALUE',
          Version: 1,
          LastModifiedDate: 1546551668.495,
          ARN: 'arn:aws:ssm:eu-test-1:123:NAME'
        }
      })
    });
    AWSMock.setSDKInstance(AWS);
    AWSMock.mock('SSM', 'GetParameter', ssmGetParameterPromise);
    amazonService = new AmazonService();

    console.log(await amazonService.getParam('NAME'))

    await expect(amazonService.getParam('NAME')).resolves.toBe('VALUE')
  })
});

当调用 amazonService.getParam 时,我得到 undefined

正如我在示例中所看到的那样,它们在被模拟后立即初始化 new AWS.SSM() 并从测试中调用它,但我想通过调用我的函数来实现这一点。调用我的函数时似乎没有模拟 SSM。

有什么正确的建议吗?

您不需要模拟 ./amazon.service.ts 模块。这是不使用 aws-sdk-mock.

的单元测试解决方案

例如

amazon.service.ts:

import * as AWS from 'aws-sdk';

export class AmazonService {
  parameterStore: AWS.SSM;

  constructor() {
    this.parameterStore = new AWS.SSM();
  }

  async getParam(param) {
    let self = this;
    console.log('IN getPARAM', param);
    return new Promise(function (resolve, reject) {
      self.parameterStore.getParameter(
        {
          Name: param,
          WithDecryption: true,
        },
        function (err, data) {
          if (err) {
            console.log('Error ', err);
            return resolve({ Error: 'ParameterNotFound' });
          }
          console.log('RES ', data.Parameter!.Value);
          return resolve(data.Parameter!.Value);
        },
      );
    });
  }
}

amazon.service.spec.ts:

import * as AWS from 'aws-sdk';
import { AmazonService } from './amazon.service';
import { mocked } from 'ts-jest/utils';
import { AWSError } from 'aws-sdk';
import { GetParameterResult } from 'aws-sdk/clients/ssm';

jest.mock('aws-sdk', () => {
  const mSSMInstance = {
    getParameter: jest.fn(),
  };
  const mSSM = jest.fn(() => mSSMInstance);

  return { SSM: mSSM };
});

describe('amazon service mock', () => {
  let amazonService: AmazonService;

  it('should get Parameter from Parameter Store', async () => {
    amazonService = new AmazonService();
    expect(AWS.SSM).toBeCalled();
    const mSSMInstance = new AWS.SSM();
    const mData = {
      Parameter: {
        Name: 'NAME',
        Type: 'SecureString',
        Value: 'VALUE',
        Version: 1,
        LastModifiedDate: new Date(1995, 11, 17),
        ARN: 'arn:aws:ssm:eu-test-1:123:NAME',
      },
    };
    mocked(mSSMInstance.getParameter).mockImplementationOnce(
      (params, callback?: (err: AWSError | null, data: GetParameterResult) => void): any => {
        if (callback) {
          callback(null, mData);
        }
      },
    );
    const actual = await amazonService.getParam('NAME');
    expect(actual).toBe('VALUE');
  });
});

带有覆盖率报告的单元测试结果:

 PASS  Whosebug/61871955/amazon.service.spec.ts (9.613s)
  amazon service mock
    ✓ should get Parameter from Parameter Store (19ms)

  console.log
    IN getPARAM NAME

      at AmazonService.<anonymous> (Whosebug/61871955/amazon.service.ts:12:13)

  console.log
    RES  VALUE

      at Whosebug/61871955/amazon.service.ts:24:19

-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   86.67 |       50 |     100 |   85.71 |                   
 amazon.service.ts |   86.67 |       50 |     100 |   85.71 | 21-22             
-------------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        10.925s