我有这个函数从特定文件夹存储桶获取特定s3文件夹中的fileNames列表,如下所示:
public List<String> listFilesFromS3Bucket(String bucketName, String folderName, String fileNamePrefix) {
List<String> fileNames = new ArrayList<>();
String folderPathPrefix = folderName + fileNamePrefix;
ObjectListing listing = s3Client.listObjects(bucketName, folderPathPrefix);
List<S3ObjectSummary> s3ObjectSummaries = listing.getObjectSummaries();
for (ListIterator<S3ObjectSummary> iterator = s3ObjectSummaries.listIterator(); iterator.hasNext();) {
String keyName = iterator.next().getKey();
if (!keyName.endsWith("/")) {
fileNames.add(StringUtils.substringAfterLast(keyName, "/"));
}
}
log.info("Total {} files to process", fileNames.size());
return fileNames;
}
现在我需要测试这段代码,我创建了一个s3client的模拟并验证了对listObjects的调用。我不是测试来验证对listObjects的调用以及我做的 -
Mockito.Verify(s3Client).listObjects(bucketname, prefix);
但是我应该如何测试剩下的代码,我对测试很陌生?
答案 0 :(得分:0)
你的问题是一个有点广泛的问题,但如果我是你,我会测试整个 listFilesFromS3Bucket方法。这样,您可以确定您的代码正确地作为一个单元而不是单个部件的功能。完成后,测试函数的各种预期输入以验证预期输出,错误处理等。这也将解决和分离您可能需要实现的函数中的问题。
答案 1 :(得分:0)
我正常测试的是3件事。
1)给定输入的输出(通常超过1次测试)
2)是否对注入的对象执行了正确的调用。例如对于给定的输入,传递给该注入对象的方法调用的正确参数。
3)当方法可能抛出异常时。测试是否对于给定的输入抛出了正确的异常。
还要确保覆盖所有路径。您的IDE可以帮助您解决此问题
对于您的方法,我会测试以下内容:
1)测试Mockito.Verify(s3Client).listObjects(bucketname, prefix);
是否只执行一次。
2)测试多个输入的输出文件名列表。使用输入使循环执行0,1和多次
希望这能回答你的问题
答案 2 :(得分:0)
我在您的代码中看到的一个缺陷是listing
始终为非null。验证它始终是这种情况,因为您的代码假定它。类似于 - s3ObjectSummaries
&amp; keyName
引用。
如果listing
为空,您的代码是否正常?
!keyName.endsWith("/")
为true
时执行测试,false
时执行另一项测试。
您的代码对任何RuntimeException
的行为如何?你想怎么处理?
这些只是您将为您的方法测试的示例事物,并且不是通过一种测试方法实现的,而是通过许多测试方法实现,即对于您的单一目标方法,您将编写许多涵盖所有场景的测试方法。代码路径并最终纠正您的代码(如果您发现任何缺陷)。
将任何代码覆盖率插件插入IDE(如果您的IDE没有提供)并尝试通过所有这些不同的测试方法实现100%的代码覆盖率。
你不应该限制自己使用一些目标方法的测试方法 - 除非你实现100%的代码覆盖率(如果可能的话),你应该继续。如果您的单元测试结果如此,您也应该愿意更改代码。
Mockito when
用于为各种场景设置各种数据,verify
将用于检查该模拟的调用等。列出了几个非常好的样本here
此外,单元测试不是集成测试,所以在我看来,你应该总是编写单元测试来模拟你的s3Client
或任何这样的依赖。