如何使用MockK模拟S3 PutObject请求?解决匹配失败异常
问题
我有一个将数据上传至S3的函数,代码如下:
val s3Client = S3Client.create() data class S3Object( val bucket: String, val key: String, val contents: String, val contentType: String ) fun putS3Object(s3Object: S3Object){ val putObjectRequest = PutObjectRequest.builder() .bucket(s3Object.bucket) .key(s3Object.key.toString()) .contentType(s3Object.contentType) .build() s3Client.putObject(putObjectRequest, RequestBody.fromString(s3Object.contents)) }
我尝试按如下方式进行模拟:
every { S3Client.create()} returns s3Client val s3Object = S3Object("test-bucket", "/test/key", "test-event", "application/json; charset=UTF-8") val putRequest = PutObjectRequest.builder() .bucket(s3Object.bucket) .contentType(s3Object.contentType) .key(s3Object.key) .build() val putObjectResponse = PutObjectResponse .builder() .build() every{ s3Client.putObject(putObjectRequest, RequestBody.fromString(s3Object.contents))} answers {putObjectResponse}
运行测试时出现以下MockK异常:
io.mockk.MockKException: no answer found for: S3Client(#4).putObject(PutObjectRequest(Bucket=test-bucket, ContentType=application/json; charset=UTF-8, Key="/test/key"), software.amazon.awssdk.core.sync.RequestBody@49322d04)
解决方法
核心原因
MockK匹配失败是因为你手动创建的putRequest和RequestBody实例,跟被测试函数内部生成的不是同一个对象。MockK默认严格匹配对象实例,因此找不到对应的模拟方法。
具体修复步骤
1. 放宽请求对象的匹配条件
不用固定实例匹配,改用匹配器验证请求的关键属性是否符合预期:
every { s3Client.putObject( match { req -> req.bucket() == s3Object.bucket && req.key() == s3Object.key && req.contentType() == s3Object.contentType }, any() ) } returns putObjectResponse
2. 精准验证请求体内容
如果需要确认RequestBody的内容,可添加内容匹配逻辑:
every { s3Client.putObject( match { req -> req.bucket() == s3Object.bucket && req.key() == s3Object.key && req.contentType() == s3Object.contentType }, match { body -> body.asByteArray().contentEquals(s3Object.contents.toByteArray()) } ) } returns putObjectResponse
3. 简化匹配(可选)
若不需要验证请求细节,可直接用泛型匹配器简化代码:
every { s3Client.putObject(any<PutObjectRequest>(), any<RequestBody>()) } returns putObjectResponse
额外注意
被测试函数中调用了s3Object.key.toString(),尽管当前测试用例的key是String类型,但如果后续key类型变更,需确保测试与实际逻辑一致,避免行为差异。
内容的提问来源于stack exchange,提问作者CyberPunk
相关产品推荐
相关产品推荐

