From afb93479d25d2ad36d0f3322540a321db09512d3 Mon Sep 17 00:00:00 2001 From: Oguzhan Soykan Date: Mon, 28 Oct 2024 16:23:47 +0100 Subject: [PATCH] Improve tests for invocation count --- projects/build.gradle.kts | 8 +- .../framewokUseCases/MediatorUseCases.kt | 27 ++++--- .../kediatr/framewokUseCases/models.kt | 76 ++++++++++++++----- .../trendyol/kediatr/quarkus/MediatorTests.kt | 10 +-- 4 files changed, 87 insertions(+), 34 deletions(-) diff --git a/projects/build.gradle.kts b/projects/build.gradle.kts index 8374534..5f654d7 100644 --- a/projects/build.gradle.kts +++ b/projects/build.gradle.kts @@ -9,8 +9,8 @@ kover { filters { excludes { androidGeneratedClasses() - this.packages("**generated**") - this.classes("**generated**") + packages("**generated**") + classes("**generated**") } } } @@ -23,6 +23,10 @@ subprojects { kotlin { jvmToolchain(17) + compilerOptions { + freeCompilerArgs = listOf("-Xjsr305=strict") + allWarningsAsErrors = true + } } dependencies { diff --git a/projects/kediatr-core/src/testFixtures/kotlin/com/trendyol/kediatr/framewokUseCases/MediatorUseCases.kt b/projects/kediatr-core/src/testFixtures/kotlin/com/trendyol/kediatr/framewokUseCases/MediatorUseCases.kt index 32e91d8..91320f0 100644 --- a/projects/kediatr-core/src/testFixtures/kotlin/com/trendyol/kediatr/framewokUseCases/MediatorUseCases.kt +++ b/projects/kediatr-core/src/testFixtures/kotlin/com/trendyol/kediatr/framewokUseCases/MediatorUseCases.kt @@ -4,7 +4,8 @@ import com.trendyol.kediatr.HandlerNotFoundException import io.kotest.assertions.throwables.shouldThrow import io.kotest.matchers.shouldBe import kotlinx.coroutines.test.runTest -import org.junit.jupiter.api.* +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows abstract class MediatorUseCases : MediatorDIConvention { @Test @@ -26,8 +27,10 @@ abstract class MediatorUseCases : MediatorDIConvention { @Test fun commandWithResult() = runTest { val count = 0 - val result = testMediator.send(TestCommandWithResult(count)) + val command = TestCommandWithResult(count) + val result = testMediator.send(command) result.value shouldBe count + 1 + command.invocationCount() shouldBe 1 } @Test @@ -41,22 +44,29 @@ abstract class MediatorUseCases : MediatorDIConvention { @Test fun notification() = runTest { - testMediator.publish(TestNotification()) + val notification = TestNotification() + testMediator.publish(notification) + notification.invocationCount() shouldBe 1 } @Test - fun `should process command with async pipeline`() = runTest { - testMediator.send(TestPipelineCommand()) + fun pipeline() = runTest { + val command = TestPipelineCommand() + testMediator.send(command) + command.visitedPipelines() shouldBe setOf( + ExceptionPipelineBehavior::class.simpleName, + LoggingPipelineBehavior::class.simpleName + ) } @Test - fun `should process exception in async handler`() = runTest { + fun command_throws_exception() = runTest { val act = suspend { testMediator.send(TestBrokenCommand()) } assertThrows { act() } } @Test - fun `should throw exception if given async query does not have handler bean`() = runTest { + fun query_without_handler() = runTest { val exception = shouldThrow { testMediator.send(NonExistQuery()) } @@ -65,9 +75,8 @@ abstract class MediatorUseCases : MediatorDIConvention { } @Test - fun `should retrieve result from async query handler bean`() = runTest { + fun query() = runTest { val result = testMediator.send(TestQuery(1)) - result shouldBe "hello 1" } } diff --git a/projects/kediatr-core/src/testFixtures/kotlin/com/trendyol/kediatr/framewokUseCases/models.kt b/projects/kediatr-core/src/testFixtures/kotlin/com/trendyol/kediatr/framewokUseCases/models.kt index 37f8d08..989bd0e 100644 --- a/projects/kediatr-core/src/testFixtures/kotlin/com/trendyol/kediatr/framewokUseCases/models.kt +++ b/projects/kediatr-core/src/testFixtures/kotlin/com/trendyol/kediatr/framewokUseCases/models.kt @@ -1,3 +1,5 @@ +@file:Suppress("UNCHECKED_CAST") + package com.trendyol.kediatr.framewokUseCases import com.trendyol.kediatr.* @@ -5,13 +7,14 @@ import io.kotest.matchers.shouldNotBe class TestNonExistCommand : Command -class TestCommand : Command +class TestCommand : Command, EnrichedWithMetadata() class TestCommandHandler( private val mediator: Mediator ) : CommandHandler { override suspend fun handle(command: TestCommand) { mediator shouldNotBe null + command.incrementInvocationCount() } } @@ -21,33 +24,69 @@ class Result( class NonExistCommandWithResult : CommandWithResult -data class TestCommandWithResult(val invoked: Int = 0) : CommandWithResult +data class TestCommandWithResult( + val invoked: Int = 0 +) : CommandWithResult, EnrichedWithMetadata() class TestCommandWithResultCommandHandler( val mediator: Mediator ) : CommandWithResultHandler { - override suspend fun handle(command: TestCommandWithResult): Result = Result(command.invoked + 1) + override suspend fun handle( + command: TestCommandWithResult + ): Result = Result(command.invoked + 1).also { command.incrementInvocationCount() } } -class TestNotification : Notification +class TestNotification : Notification, EnrichedWithMetadata() class TestNotificationHandler( private val mediator: Mediator ) : NotificationHandler { override suspend fun handle(notification: TestNotification) { mediator shouldNotBe null + notification.incrementInvocationCount() } } -class TestBrokenCommand : Command +class TestBrokenCommand : Command, EnrichedWithMetadata() + +class TestPipelineCommand : Command, EnrichedWithMetadata() + +abstract class EnrichedWithMetadata { + private val metadata = mutableMapOf() + + internal fun incrementInvocationCount() { + val invocationCount = invocationCount() + addMetadata(INVOCATION_COUNT, invocationCount + 1) + } + + fun invocationCount(): Int = getMetadata(INVOCATION_COUNT) as? Int ?: 0 + + internal fun visitedPipeline(pipeline: String) { + val visitedPipelines = visitedPipelines().toMutableSet() + visitedPipelines.add(pipeline) + addMetadata(VISITED_PIPELINES, visitedPipelines) + } + + fun visitedPipelines(): Set = getMetadata(VISITED_PIPELINES) as? Set ?: emptySet() + + private fun addMetadata(key: String, value: Any) { + metadata[key] = value + } + + private fun getMetadata(key: String): Any? = metadata[key] -class TestPipelineCommand : Command + companion object { + private const val INVOCATION_COUNT = "invocationCount" + private const val VISITED_PIPELINES = "visitedPipelines" + } +} class TestPipelineCommandHandler( val mediator: Mediator ) : CommandHandler { override suspend fun handle(command: TestPipelineCommand) { mediator shouldNotBe null + command.incrementInvocationCount() } } @@ -56,6 +95,7 @@ class TestBrokenCommandHandler( ) : CommandHandler { override suspend fun handle(command: TestBrokenCommand) { mediator shouldNotBe null + command.incrementInvocationCount() throw Exception() } } @@ -64,14 +104,13 @@ class ExceptionPipelineBehavior : PipelineBehavior { override suspend fun handle( request: TRequest, next: RequestHandlerDelegate - ): TResponse { - try { -// exceptionPipelineBehaviorHandleCounter++ - return next(request) - } catch (ex: Exception) { -// exceptionPipelineBehaviorHandleCatchCounter++ - throw ex + ): TResponse = try { + when (request) { + is EnrichedWithMetadata -> request.visitedPipeline(this::class.java.simpleName) } + next(request) + } catch (ex: Exception) { + throw ex } } @@ -80,22 +119,23 @@ class LoggingPipelineBehavior : PipelineBehavior { request: TRequest, next: RequestHandlerDelegate ): TResponse { -// loggingPipelineBehaviorHandleBeforeNextCounter++ - val result = next(request) -// loggingPipelineBehaviorHandleAfterNextCounter++ - return result + when (request) { + is EnrichedWithMetadata -> request.visitedPipeline(this::class.java.simpleName) + } + return next(request) } } class NonExistQuery : Query -class TestQuery(val id: Int) : Query +class TestQuery(val id: Int) : Query, EnrichedWithMetadata() class TestQueryHandler( private val mediator: Mediator ) : QueryHandler { override suspend fun handle(query: TestQuery): String { mediator shouldNotBe null + query.incrementInvocationCount() return "hello " + query.id } } diff --git a/projects/kediatr-quarkus-starter/src/test/kotlin/com/trendyol/kediatr/quarkus/MediatorTests.kt b/projects/kediatr-quarkus-starter/src/test/kotlin/com/trendyol/kediatr/quarkus/MediatorTests.kt index 22f3987..760cae7 100644 --- a/projects/kediatr-quarkus-starter/src/test/kotlin/com/trendyol/kediatr/quarkus/MediatorTests.kt +++ b/projects/kediatr-quarkus-starter/src/test/kotlin/com/trendyol/kediatr/quarkus/MediatorTests.kt @@ -1,6 +1,6 @@ package com.trendyol.kediatr.quarkus -import com.trendyol.kediatr.* +import com.trendyol.kediatr.Mediator import com.trendyol.kediatr.framewokUseCases.* import io.quarkus.test.junit.QuarkusTest import jakarta.enterprise.inject.Produces @@ -29,10 +29,10 @@ class MediatorTests : MediatorUseCases() { fun notificationHandler(mediator: Mediator) = TestNotificationHandler(mediator) @Produces - fun pipelineBehaviors(): List = listOf( - ExceptionPipelineBehavior(), - LoggingPipelineBehavior() - ) + fun pipeline1() = ExceptionPipelineBehavior() + + @Produces + fun pipeline2() = LoggingPipelineBehavior() @Produces fun provideQueryHandler(mediator: Mediator) = TestQueryHandler(mediator)