如何使用Mockito对触发S3Event的Lambda函数做单元测试?
问题根因
你有两个核心错误导致验证失败:
- 对象不匹配:你调用
when(s3EventMock.getRecords()).thenReturn(mockRecords)返回的是mockRecords对象,但你verify的却是另一个完全独立的mock对象notificationRecords,两个对象没有关联,自然监测不到调用。 - 调用方法不匹配:你的handler逻辑里是用
forEach遍历S3Event的记录列表,forEach是Iterable接口的方法,并不会调用List的get(0)方法,所以哪怕你对象关联对了,验证get(0)也不会通过。
修复方案
第一步:关联正确的mock List对象
把返回值改成你要verify的notificationRecords:
when(s3EventMock.getRecords()).thenReturn(notificationRecords);
第二步:补全List的遍历相关mock逻辑
因为你用的是forEach遍历,需要让mock的List返回你构造的mockRecord,同时适配Iterable的迭代逻辑:
// 给mock的notificationRecords配置迭代逻辑,返回你创建的mock notificationRecord when(notificationRecords.iterator()).thenReturn(Collections.singletonList(notificationRecord).iterator()); // 补全后续链式调用的mock返回 when(notificationRecord.getS3()).thenReturn(s3Entity); when(s3Entity.getBucket()).thenReturn(s3BucketEntity); when(s3BucketEntity.getName()).thenReturn(S3_BUCKET_NAME); when(s3Entity.getObject()).thenReturn(s3ObjectEntity); when(s3ObjectEntity.getKey()).thenReturn(S3_FILE_NAME); when(s3Client.getObject(S3_BUCKET_NAME, S3_FILE_NAME)).thenReturn(s3Object);
第三步:改成验证正确的调用方法
把对get(0)的验证改成对迭代逻辑的验证,或者直接验证你实际的业务逻辑调用即可,比如:
// 验证forEach触发了迭代器调用 verify(notificationRecords, times(1)).iterator(); // 也可以直接验证后续业务逻辑的调用,比如s3Client的getObject是否被正确调用 verify(s3Client, times(1)).getObject(eq(S3_BUCKET_NAME), eq(S3_FILE_NAME));
内容的提问来源于stack exchange,提问作者parthc
相关产品推荐
相关产品推荐

