"Mancanti regione in config" dopo il tentativo di mock SecretsManager con Scherzo

0

Domanda

Attualmente sto tentando di mock AWS SecretsManager per il mio test di unità con Scherzo, e ogni volta mi colpisce con la ConfigError Il mio codice è un po ' come questo

//index.ts
import SM from "aws-sdk/clients/secretsmanager"
const secretManagerClient = new SM()
...
export const randomMethod = async (a: string, b: string) => {
  let secret
  const personalToken = {
    SecretId: process.env.secretId,
  }
  secretManagerClient
    .getSecretValue(personalToken, (err, data) => {
      if (err) {
        console.error(`[SECRETS MANAGER] Error fetching personal token : ${err}`)
      } else if (data && data.SecretString) {
        secret = data.SecretString
      }
    })
}

Il mio mock va come questa :

//index.test.js
const mockGetSecretValue = jest.fn((SecretId) => {
  switch (SecretId) {
    case process.env.GITHUB_PERSONAL_TOKEN:
      return {
        SecretString: process.env.GITHUB_PERSONAL_TOKEN_VALUE,
      }
    default:
      throw Error("secret not found")
  }
})

jest.mock("aws-sdk/clients/secretsmanager", () => {
  return jest.fn(() => {
    return {
      getSecretValue: jest.fn(({ SecretId }) => {
        return mockGetSecretValue(SecretId)
      }),
      promise: jest.fn(),
    }
  })
})

Tuttavia, ottengo questo errore gettato su di me : ConfigError: Missing region in config, capisco che in una certa misura, comunque, non capisco perché qui avviene il beffardo parte...

Grazie in anticipo!

EDIT: Grazie per la 1 ° risposta, sono riuscito a smettere di avere questo errore. Tuttavia, l' getSecretValue() il metodo non restituisce il valore Segreto voglio.

aws-sdk jestjs mocking node.js
2021-11-15 16:00:57
2
0

NON si deve usare il callback di .getSecretValue() con il metodo di .promise() insieme. Basta scegliere uno di loro. L'errore significa non prendere in giro la secretsmanager classe correttamente di aws-sdk.

E. g.

index.ts:

import SM from 'aws-sdk/clients/secretsmanager';
const secretManagerClient = new SM();

export const randomMethod = async () => {
  const personalToken = {
    SecretId: process.env.secretId || '',
  };
  try {
    const data = await secretManagerClient.getSecretValue(personalToken).promise();
    return data.SecretString;
  } catch (err) {
    console.error(`[SECRETS MANAGER] Error fetching personal token : ${err}`);
  }
};

index.test.ts:

import { randomMethod } from '.';
import SM from 'aws-sdk/clients/secretsmanager';
import { mocked } from 'ts-jest/utils';
import { PromiseResult } from 'aws-sdk/lib/request';

jest.mock('aws-sdk/clients/secretsmanager', () => {
  const mSecretManagerClient = {
    getSecretValue: jest.fn().mockReturnThis(),
    promise: jest.fn(),
  };
  return jest.fn(() => mSecretManagerClient);
});

describe('69977310', () => {
  test('should get secret value', async () => {
    process.env.secretId = 's1';
    const mSecretManagerClient = mocked<InstanceType<typeof SM>>(new SM());
    const mGetSecretValueRequest = mocked(mSecretManagerClient.getSecretValue());

    mGetSecretValueRequest.promise.mockResolvedValue({
      SecretString: JSON.stringify({ password: '123456' }),
    } as PromiseResult<any, any>);
    const actual = await randomMethod();
    expect(actual).toEqual(JSON.stringify({ password: '123456' }));
    expect(mSecretManagerClient.getSecretValue as jest.Mocked<any>).toBeCalledWith({ SecretId: 's1' });
  });

  test('should throw error', async () => {
    process.env.secretId = 's1';
    const logSpy = jest.spyOn(console, 'error').mockImplementation(() => 'suppress error log for testing');
    const mSecretManagerClient = mocked<InstanceType<typeof SM>>(new SM());
    const mGetSecretValueRequest = mocked(mSecretManagerClient.getSecretValue());

    const mError = new Error('network');
    mGetSecretValueRequest.promise.mockRejectedValue(mError);
    await randomMethod();
    expect(logSpy).toBeCalledWith(`[SECRETS MANAGER] Error fetching personal token : ${mError}`);
    expect(mSecretManagerClient.getSecretValue as jest.Mocked<any>).toBeCalledWith({ SecretId: 's1' });
  });
});

risultato del test:

 PASS  examples/69977310/index.test.ts (7.722 s)
  69977310
    ✓ should get secret value (4 ms)
    ✓ should throw error (1 ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |     100 |       50 |     100 |     100 |                   
 index.ts |     100 |       50 |     100 |     100 | 6                 
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        8.282 s, estimated 10 s

pacchetto le versioni:

"aws-sdk": "^2.875.0",
"typescript": "^4.1.2",
"jest": "^26.6.3",
2021-11-16 09:29:00

Grazie per la tua risposta, hai ragione, ho letto male il AWS documentazione di SDK. Tuttavia, sto cercando di fare questo lavoro. Per ulteriori contesto, attualmente sto unità di prova di una lambda che utilizza il randomMethod()e sto cercando di collegare tale metodo per questo deriso SecretsManager istanza, e pur non avendo la config di errore in più, l' getSecretValue() non restituisce il segreto voglio. Ho aggiornato il codice di cui sopra.
Fares
0

Ho trascurato il fatto che stavo usando una callback per bypassare il promise().

Il seguente è il codice corretto:

const mockGetSecretValue = jest.fn((SecretId, callback) => {
  console.log("secretId", SecretId)
  switch (SecretId) {
    case process.env.GITHUB_PERSONAL_TOKEN:
      const data = {
        SecretString: process.env.GITHUB_PERSONAL_TOKEN_VALUE,
      }
      callback(null, data)
      break;
    default:
      const err = new Error("secret not found")
      throw err
  }
})

jest.mock("aws-sdk/clients/secretsmanager", () => {
  return jest.fn(() => {
    return {
      promise: jest.fn(),
      getSecretValue: jest.fn(({ SecretId }, callback) => {
        return mockGetSecretValue(SecretId, callback)
      }),
    }
  })
})

Grazie ancora per il vostro aiuto @slideshowp2!

2021-11-16 14:24:07

In altre lingue

Questa pagina è in altre lingue

Русский
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................