我正在为从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)

07-22 04:11