我正在尝试使用API网关,lambda和DynamoDB创建小型REST API,同时遵循TDD等良好的开发实践。我习惯于使用DI容器来配置我的对象,这非常适合进行模拟和测试。在MVC框架中,将只有一个入口点,在这里我可以定义容器配置,引导应用程序并调用控制器来处理事件。我可以独立于应用程序的其余部分来测试控制器,并注入模拟的依赖项。我无法弄清楚如何将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代码,以便对其进行正确的单元测试?
答案 0 :(得分:2)
在我目前正在研究的项目中,我们采用的一种方法是分解需求,因此handler
负责:
然后它调用另一个完成大部分工作的函数,我们可以单独对其进行测试。将handler
视为控制器,将其他功能视为完成工作的服务。
在您的特定情况下,可能看起来像这样:
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
现在可以在单元级别使用回购对象和所需输入的测试加倍来执行。 UserRepo
已经通过Dynamo客户端的构造函数注入而解耦,因此也应该可以测试。
我们还进行了集成级别的测试,这些测试仅 模拟了AWS开发工具包的内容(您也可以使用传输层模拟或类似aws-sdk-mock
的东西)以及端到端的测试来确保整体系统一起工作。