cari

Rumah  >  Soal Jawab  >  teks badan

Sinon melaksanakan simulasi panggilan sambungan AWS DynamoDB

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粉633733146P粉633733146295 hari yang lalu411

membalas semua(2)saya akan balas

  • P粉714780768

    P粉7147807682024-03-22 18:19:12

    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

    balas
    0
  • P粉476046165

    P粉4760461652024-03-22 16:16:37

    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

    balas
    0
  • Batalbalas