javascript - 如何构建 lambda 代码以实现可测试性

标签 javascript node.js amazon-web-services aws-lambda

我正在尝试使用 API 网关、lambda 和 DynamoDB 制作一个小型 REST API,同时遵循 TDD 等良好的开发实践。我习惯于使用 DI 容器来提供我的对象,这非常适合模拟和测试。在 MVC 框架中,会有一个入口点,我可以在其中定义容器配置、引导应用程序并调用 Controller 来处理事件。我可以独立于应用程序的其余部分测试 Controller ,并注入(inject)模拟依赖项。我不知道如何将 lambda 函数可能具有的依赖项与 lambda 函数本身分离。例如:

const { DynamoDB } = require('aws-sdk')
const { UserRepo } = require('../lib/user-repo')

const client   = new DynamoDB({ region: process.env.REGION }) // Should be resolved by DI container
const userRepo = new UserRepo(client) // Should be resolved by DI container

exports.handler = async (event) => {
  return userRepo.get(event.id)
}

谁能指导我构建 lambda 代码的正确方向,以便对其进行正确的单元测试?

最佳答案

在我目前从事的项目中,我们采用的一种方法是拆分需求,因此 handler 负责:

  • 创建客户;
  • 从环境中提取任何配置;和
  • 从事件中获取参数。

然后它调用另一个函数来完成大部分工作,我们可以单独测试它。将 handler 想象成 Controller ,将其他功能想象成完成工作的服务。

在您的特定情况下,这可能看起来像:

const { DynamoDB } = require('aws-sdk');
const { UserRepo } = require('../lib/user-repo');

const doTheWork = (repo, id) => repo.get(id);

exports.handler = async (event) => {
  const client = new DynamoDB({ region: process.env.REGION });
  const userRepo = new UserRepo(client); 
  return doTheWork(userRepo, event.id);
}

doTheWork 现在可以在单元级别使用 repo 对象的测试替身和您想要的任何输入来练习。 UserRepo 已经通过 Dynamo 客户端的构造函数注入(inject)解耦了,所以它也应该非常容易测试。

我们还在集成级别进行测试, 模拟 AWS SDK 的东西(您也可以使用传输层模拟或类似 aws-sdk-mock 的东西)以及确保整个系统正常工作的 E2E 测试一起。

关于javascript - 如何构建 lambda 代码以实现可测试性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55400782/

相关文章:

javascript - 如何在后续保存时重新启动 Gulp 任务?

node.js - npm 包 "JavaScript heap out of memory"

ios - dynamodb,MobileHub 不工作

javascript - 为什么 [Object] 在 node.js 中打印到控制台而不是对象的内容?

javascript - 安装 webpack 和 babel 后 npm 开始不工作

node.js - Node JS - 加载和修改 SVG 文件

python - 从 SageMaker 将数据帧上传到 AWS S3 存储桶

amazon-web-services - 使用 AWS ACM 证书配置 Gloo 虚拟服务 SSL

javascript - 对类数组对象进行排序 Angular

json - Elasticsearch js 批量索引类型错误