在 sinon 中模拟对 AWS DynamoDB 的连接调用

问题描述 投票:0回答:1

我在 API 网关中有一个端点,它映射到 AWS 中的 Lambda 函数。在为端点的新处理函数编写测试用例时,我不希望 spec 文件调用实际 API 或连接到 DynamoDB。我尝试添加一个

sinon.stub
,但它仍然调用连接到 DynamoDB 并且测试用例失败。我无法找到存根出错的地方。

Handler.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"
  };
  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();
    }
  });
});

错误:

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

我控制台记录了

err
对象,它给了我这个错误,这让我觉得它正在尝试连接到 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]
}

相关:如何测试从 AWS DynamoDB 返回数据的方法

javascript amazon-web-services amazon-dynamodb aws-api-gateway sinon
1个回答
0
投票

你在嘲笑测试文件中声明的

db
- 而不是
db
实际使用的
saveUser

解决方案是将 db 声明移动到它自己的模块中,比如:db.js

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

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

module.exports = db;

然后从

saveUser
的模块和测试中导入它 - 这样我们就可以模拟
db
使用的同一个
saveUser
实例。

© www.soinside.com 2019 - 2024. All rights reserved.