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

huangapple go评论69阅读模式
英文:

How to test a method which returns data from AWS DynamoDB

问题

I have created a new API endpoint in API Gateway,映射了我的AWS Lambda函数,并想为处理请求的JavaScript方法编写测试用例。该方法使用aws-sdk节点模块创建与AWS DynamoDB的连接,将传递的值保存到数据库,并返回一个带有相关数据的Promise。我不希望spec触发对实际DynamoDB的调用或创建新条目。我尝试使用存根,但仍然出现错误,指示测试用例失败。

Handler.js:

saveUser(userName, logger) {
  const Item = {
    id: uuid.v4(),
    userName,
    ttl: parseInt(Date.now() / 1000) + 900 // 从现在起的15分钟后过期
  };
  const params = {
    TableName: "my-table-name"
  };
  logger.log(`将新用户名保存到DynamoDB:${JSON.stringify(params)}`);

  return new Promise(function(resolve, reject) {
    db.put(params, function(err, _) {
      if (err) {
        logger.exception(`无法连接到DynamoDB进行创建:${err}`);
        reject({
          statusCode: 404,
          err
        });
      } else {
        logger.log(`已将数据保存到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("测试saveUser()方法", async function(done) {
    const { saveUser } = userHandler;

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

    try {
      const result = await saveUser("示例用户", {
        log: () => {},
        exception: () => {}
      });

      expect(result).to.be.equal({
        data: "一些数据"
      });
      done();
    } catch (err) {
      console.log(err);
      done();
    }
  });
});

错误:

错误:解析方法过于具体。指定回调*或*返回Promise;不要同时使用两者。
英文:

I have created a new API endpoint in API Gateway mapped my AWS Lambda function and want to write test cases for the JavaScript method which handles requests made to the endpoint. The method creates a connection to AWS DynamoDB using the aws-sdk node module to save passed values to the database and returns a Promise with relevant data. I do not want the spec to trigger a call to the actual DynamoDB or create a new entry to it. I tried using a stub, but it still gave me an error stating that the test-case failed.

Handler.js:

<!-- begin snippet: js hide: false console: false babel: false -->

<!-- language: lang-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: &quot;my-table-name&quot;
  };
  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
        });
      }
    });
  });
}

<!-- end snippet -->

Handler.spec.js:

<!-- begin snippet: js hide: false console: false babel: false -->

<!-- language: lang-js -->

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

describe(&quot;user-name-handler&quot;, function() {
  const sandbox = sinon.createSandbox();
  afterEach(() =&gt; sandbox.restore());

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

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

    try {
      const result = await saveUser(&quot;Sample User&quot;, {
        log: () =&gt; {},
        exception: () =&gt; {}
      });

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

<!-- end snippet -->

Error:

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

答案1

得分: 1

尝试将 function(done) 替换为 function() 并移除所有对 done() 的调用;

英文:

Try to replace function(done) with function() and remove all the calls to done();

huangapple
  • 本文由 发表于 2023年5月7日 16:05:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/76192814.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定