簡體   English   中英

如何模擬使用 AWS 資源的 typescript 服務和功能?

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

我有一個 Typescript 后端結構,我想為所有功能創建單元測試。 我正在為 mocking AWS 使用JESTaws-skd-mock 我嘗試了一些事情,但似乎我沒有做正確的事情。

我有這項服務,我從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 文件,在我的測試文件(amazon.service.spect.ts) 中模擬 SSM.getParameter 和響應:

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 被調用時,我得到了未定義

正如我在示例中查看的那樣,他們在模擬后立即初始化新的 AWS.SSM() 並從測試中調用它,但我想通過調用我的 function 來實現這一點。 當我的 function 被調用時,似乎沒有嘲笑 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  stackoverflow/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> (stackoverflow/61871955/amazon.service.ts:12:13)

  console.log
    RES  VALUE

      at stackoverflow/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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM