Sinon melaksanakan simulasi panggilan sambungan AWS DynamoDB
P粉633733146
P粉633733146 2024-03-21 21:36:37
0
2
389

Saya mempunyai titik akhir dalam Gateway API yang memetakan kepada fungsi Lambda dalam AWS. Apabila menulis kes ujian untuk fungsi pengendali baharu titik akhir, saya tidak mahu fail spec memanggil API sebenar atau menyambung ke DynamoDB. Saya cuba menambah sinon.stub tetapi ia masih memanggil sambung ke DynamoDB dan kes ujian gagal. Saya tidak dapat mencari di mana silapnya tunas.

pengendali.js:

saveUser(userName, logger) {
  const Item = {
    id: uuid.v4(),
    userName,
    ttl: parseInt(Date.now() / 1000) + 900 // expire the name after 15 minutes from now
  };
  const params = {
    TableName: "my-table-name",
    Item
  };
  logger.log(`Saving new user name to DynamoDB: ${JSON.stringify(params)}`);

  return new Promise(function(resolve, reject) {
    db.put(params, function(err, _) {
      if (err) {
        logger.exception(`Unable to connect to DynamoDB to create: ${err}`);
        reject({
          statusCode: 404,
          err
        });
      } else {
        logger.log(`Saved data to DynamoDB: ${JSON.stringify(Item)}`);
        resolve({
          statusCode: 201,
          body: Item
        });
      }
    });
  });
}

Handler.spec.js:

import AWS from "aws-sdk";
const db = new AWS.DynamoDB.DocumentClient({
  apiVersion: "2012-08-10"
});

describe("user-name-handler", function() {
  const sandbox = sinon.createSandbox();
  afterEach(() => sandbox.restore());

  it("Test saveUser() method", async function(done) {
    const {
      saveUser
    } = userHandler;

    sandbox.stub(db, "put")
      .returns(new Promise((resolve, _) => resolve({
        statusCode: 200
      })));

    try {
      const result = await saveUser("Sample User", {
        log: () => {},
        exception: () => {}
      });

      expect(result).to.be.equal({
        data: "some data"
      });
      done();
    } catch (err) {
      console.log(err);
      done();
    }
  });
});

Ralat:

Error: Resolution method is overspecified. Specify a callback *or* return a Promise; not both.

Saya log objek err melalui konsol dan ia memberi saya ralat ini, yang membuatkan saya fikir ia cuba menyambung ke DynamoDB.

Error: connect ENETUNREACH 127.0.0.1:80
  at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1144:16) {
message: 'Missing credentials in config, if using AWS_CONFIG_FILE, set AWS_SDK_LOAD_CONFIG=1',       
errno: 'ENETUNREACH',
code: 'CredentialsError',
syscall: 'connect',
address: '127.0.0.1',
port: 80,
time: 2023-05-07T10:45:25.835Z,
originalError: {
  message: 'Could not load credentials from any providers',
  errno: 'ENETUNREACH',
  code: 'CredentialsError',
  syscall: 'connect',
  address: '127.0.0.1',
  port: 80,
  time: 2023-05-07T10:45:25.835Z,
  originalError: [Object]
}

Berkaitan: Cara menguji kaedah yang mengembalikan data daripada AWS DynamoDB

P粉633733146
P粉633733146

membalas semua(2)
P粉714780768

Anda mengejek db - 而不是 saveUser 实际使用的 db yang diisytiharkan dalam fail ujian.

Penyelesaian adalah untuk memindahkan pengisytiharan db ke modulnya sendiri, contohnya: db.js

const AWS = require("aws-sdk");

const db = new AWS.DynamoDB.DocumentClient({
  apiVersion: "2012-08-10"
});

module.exports = db;

Kemudian dari saveUser 模块和测试中导入它 - 这样我们就可以模拟 saveUser 使用的同一个 db contoh.

Dikemas kini

Saya berjaya menjalankan ujian menggunakan kod berikut:

Kod ujian:

const sinon = require('sinon');
const { saveUser } = require('../userHandler');
const { expect } = require('chai');

const db = require('../db');

describe('user-name-handler', function() {
  afterEach(() => sinon.restore());

  it('Test saveUser() method', async function() {

      sinon.stub(db, 'put')
        .returns(new Promise((resolve, _) => resolve({
            statusCode: 201,
            body: 'some data'
      })));

      try {
          const result = await saveUser(db, 'Sample User', {
            log: () => {},
            exception: () => {}
          });

          expect(result).to.deep.equal({
            statusCode: 201,
            body: 'some data'
          });
      } catch (err) {
        console.log('err', err);
      }
  });
});

Fail pengendali pengguna:

const db = require('./db');

const saveUser = (db, userName, logger) => {
  const Item = {
    id: uuid.v4(),
    userName,
    ttl: parseInt(Date.now() / 1000) + 900 // expire the name after 15 minutes from now
  };
  const params = {
    TableName: "my-table-name"
  };
  logger.log(`Saving new user name to DynamoDB: ${JSON.stringify(params)}`);

    return db.put(params, function(err, _) {
      if (err) {
        logger.exception(`Unable to connect to DynamoDB to create: ${err}`);
        return reject({
          statusCode: 404,
          err
        });
      } else {
        logger.log(`Saved data to DynamoDB: ${JSON.stringify(Item)}`);
        return resolve({
          statusCode: 201,
          body: Item
        });
      }
    });
}

module.exports = { saveUser };

pakej.json

{
  "name": "play",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "mocha --timeout 5000"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "aws-sdk": "^2.1373.0",
    "chai": "^4.3.7",
    "mocha": "^10.2.0",
    "sinon": "^15.0.4"
  }
}

Output

P粉476046165

Asingkan sambungan pangkalan data dalam fail

Kami boleh memisahkan sambungan pangkalan data ke dalam fail yang berbeza dan mengimportnya ke dalam pelaksanaan pengendali serta fail spec.

db.js

import AWS from "aws-sdk";
const db = new AWS.DynamoDB.DocumentClient({ apiVersion: "2012-08-10" });

export default db;

yields() fungsi

Stub tidak seharusnya mengembalikan Promise,而应与 .yields() pautan ke parameter yang akan diterima panggilan baliknya. Kita boleh menukar parameter untuk merangkumi pelbagai cabang kod.

Kod

describe("user-handler connection success", function () {
    const sandbox = sinon.createSandbox();
    afterEach(() => sandbox.restore());
    before(() => {
        sinon.stub(db, "put")
            .yields(null, true);
        sinon.stub(db, "get")
            .yields(null, { sampleKey: "sample value" });
        sinon.stub(db, "delete")
            .yields(null, { sampleKey: "sample value" });
    });
    after(() => {
        db.put.restore();
        db.get.restore();
        db.delete.restore();
    });

    it("Test saveUser() method success", async function () {
        const result = await userHandler.saveToken("sample user", {
            log: () => {},
            exception: () => {}
        });

        expect(result.statusCode).to.be.equal(201);
    });
});

Pautan berguna

https://www.youtube.com/watch?v=vXDbmrh0xDQ

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan