我正在为从S3触发,获取一些文件数据并将其放入另一个S3存储桶的AWS Lambda实现Java 8程序包。
这是我当前的Handler
:
public class Handler implements RequestHandler<S3Event, Void> {
private static final String TARGET_BUCKET = "some-bucket";
private AmazonS3Client s3Client = new AmazonS3Client(new DefaultAWSCredentialsProviderChain());
private Runner runner = new Runner(s3Client, TARGET_BUCKET);
@Override
public Void handleRequest(S3Event s3Event, Context context) {
runner.run(s3Event, context);
return null;
}
}
我已经将业务逻辑移到了
Runner
类,以便可以正确地对其进行测试(在AWS Lambda best practices white paper之后)。但是,我在努力查看如何传递假
S3Event
来测试run
函数。我目前的测试是:
@Test
public void putsDataIntoS3() throws IOException {
runner.run(new ObjectMapper().readValue(loadJsonFromFile("s3-event.json"), S3Event.class), context);
assertTrue(true);
}
loadJsonFromFile
在获取我传递的文件名的资源时,将其转换为输入流,然后转换为String
。但是,这会导致错误:
com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class com.amazonaws.services.lambda.runtime.events.S3Event]: can not instantiate from JSON object (missing default constructor or creator, or perhaps need to add/enable type information?)
所以我的问题是,如何通过传递伪造的
run
JSON来正确测试S3Event
函数?这些是我正在使用的与aws相关的依赖项:
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-core</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-events</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
<version>1.11.455</version>
</dependency>
编辑:
我可以这样使用
S3Event.parseJson
函数:我也看到了
parseJson
函数,可以这样使用它:@Test
public void putsFilteredDataIntoS3() throws IOException {
runner.run(new S3Event(S3Event.parseJson(loadJsonFromFile("s3-event.json")).getRecords()), context);
assertTrue(true);
}
但是,这是否是最佳做法?
最佳答案
您可以使用Mockito库并尝试模拟此S3Event
。
从JSON创建S3Event
的另一种选择:
S3EventNotification notification = S3EventNotification.parseJson(loadJsonFromFile("s3-event.json"));
S3Event event = new S3Event(notification.getRecords());
编辑:
第三种选择是将
aws-lambda-java-events
更新为2.2.4
版本,他们在其中添加了S3Event
的默认构造函数,因此您可以像这样反序列化它:objectMapper.readValue(loadJsonFromFile("s3-event.json"), S3Event.class)