As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.
Zombando no AWS SDK para Kotlin
Os desenvolvedores podem usar várias estruturas para realizar simulações em testes com o. AWS SDK para Kotlin Este tópico documenta configurações adicionais ou considerações especiais que algumas estruturas exigem.
Zombar K
Ao simular funções de extensão de todo o módulo usando o MockK
Você deve ligar mockkStatic("<MODULE_CLASS_NAME>")
antes de configurar suas simulações. Como regra geral, os nomes das classes do módulo são:
-
Paginadores:
aws.sdk.kotlin.services.<service>.paginators.PaginatorsKt
-
Garçons:
aws.sdk.kotlin.services.<service>.waiters.WaitersKt
-
Prescritores:
aws.sdk.kotlin.services.<service>.presigners.PresignersKt
Por exemplo, no teste a seguir, que inclui simulação listBucketsPaginated
— uma função de extensão do paginador — adicionamos: mockkStatic("aws.sdk.kotlin.services.s3.paginators.PaginatorsKt")
@Test fun testPaginatedListBuckets() = runTest { mockkStatic("aws.sdk.kotlin.services.s3.paginators.PaginatorsKt") val s3Client: S3Client = mockk() val s3BucketLister = S3BucketLister(s3Client) val expectedBuckets = listOf( Bucket { name = "bucket1" }, Bucket { name = "bucket2" } ) val response = ListBucketsResponse { buckets = expectedBuckets } coEvery { s3Client.listBucketsPaginated() } returns flowOf(response) val result = s3BucketLister.getAllBucketNames() assertEquals(listOf("bucket1", "bucket2"), result) }
Sem mockkStatic
isso, você vê o seguinte erro:
Missing mocked calls inside every { ... } block: make sure the object inside the block is a mock io.mockk.MockKException: Missing mocked calls inside every { ... } block: make sure the object inside the block is a mock at io.mockk.impl.recording.states.StubbingState.checkMissingCalls(StubbingState.kt:14) at io.mockk.impl.recording.states.StubbingState.recordingDone(StubbingState.kt:8) at io.mockk.impl.recording.CommonCallRecorder.done(CommonCallRecorder.kt:47) at io.mockk.impl.eval.RecordedBlockEvaluator.record(RecordedBlockEvaluator.kt:63) at io.mockk.impl.eval.EveryBlockEvaluator.every(EveryBlockEvaluator.kt:30) at io.mockk.MockKDsl.internalCoEvery(API.kt:100) at io.mockk.MockKKt.coEvery(MockK.kt:174)
No caso de uma função de extensão presigner semmockkStatic
, você pode ver:
key is bound to the URI and must not be null java.lang.IllegalArgumentException: key is bound to the URI and must not be null at aws.sdk.kotlin.services.s3.serde.GetObjectOperationSerializer.serialize(GetObjectOperationSerializer.kt:26) at aws.sdk.kotlin.services.s3.presigners.PresignersKt.presignGetObject(Presigners.kt:49) at aws.sdk.kotlin.services.s3.presigners.PresignersKt.presignGetObject$default(Presigners.kt:40) at aws.sdk.kotlin.services.s3.presigners.PresignersKt.presignGetObject-exY8QGI(Presigners.kt:30)
Código em teste
import aws.sdk.kotlin.services.s3.S3Client import aws.sdk.kotlin.services.s3.paginators.listBucketsPaginated import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.toList import kotlinx.coroutines.flow.transform import kotlinx.coroutines.runBlocking import org.slf4j.Logger import org.slf4j.LoggerFactory fun main() { val logger: Logger = LoggerFactory.getLogger(::main.javaClass) // Create an S3Client S3Client { region = "us-east-1" }.use { s3Client -> // Create service instance val bucketLister = S3BucketLister(s3Client) // Since getAllBucketNames is a suspend function, you'll need to run it in a coroutine scope runBlocking { val bucketNames = bucketLister.getAllBucketNames() logger.info("Found buckets: $bucketNames") } } } class S3BucketLister(private val s3Client: S3Client) { suspend fun getAllBucketNames(): List<String> { return s3Client.listBucketsPaginated() .transform { response -> response.buckets?.forEach { bucket -> emit(bucket.name ?: "") } } .filter { it.isNotEmpty() } .toList() } }
Classe de teste
import aws.sdk.kotlin.services.s3.S3Client import aws.sdk.kotlin.services.s3.model.Bucket import aws.sdk.kotlin.services.s3.model.ListBucketsResponse import aws.sdk.kotlin.services.s3.paginators.listBucketsPaginated import io.mockk.coEvery import io.mockk.mockk import io.mockk.mockkStatic import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test class S3BucketListerTest { @Test fun testPaginatedListBuckets() = runTest { mockkStatic("aws.sdk.kotlin.services.s3.paginators.PaginatorsKt") val s3Client: S3Client = mockk() val s3BucketLister = S3BucketLister(s3Client) val expectedBuckets = listOf( Bucket { name = "bucket1" }, Bucket { name = "bucket2" } ) val response = ListBucketsResponse { buckets = expectedBuckets } coEvery { s3Client.listBucketsPaginated() } returns flowOf(response) val result = s3BucketLister.getAllBucketNames() assertEquals(listOf("bucket1", "bucket2"), result) } }
build.gradle.kts
plugins { kotlin("jvm") version "2.1.20" application } group = "org.example" version = "1.0-SNAPSHOT" repositories { mavenCentral() } dependencies { implementation(platform(awssdk.bom)) implementation(platform("org.apache.logging.log4j:log4j-bom:2.24.3")) implementation(awssdk.services.s3) implementation("org.apache.logging.log4j:log4j-slf4j2-impl") // Testing Dependencies testImplementation(platform("org.junit:junit-bom:5.11.0")) testImplementation("org.junit.jupiter:junit-jupiter") testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3") testImplementation("io.mockk:mockk:1.14.0") } tasks.test { useJUnitPlatform() } java { toolchain { languageVersion = JavaLanguageVersion.of(21) } } application { mainClass = "org.example.S3BucketService" }
settings.gradle.kts
plugins { id("org.gradle.toolchains.foojay-resolver-convention") version "0.10.0" } rootProject.name = "mockK-static" dependencyResolutionManagement { repositories { mavenCentral() } versionCatalogs { create("awssdk") { from("aws.sdk.kotlin:version-catalog:1.4.69") } } }