diff --git a/code_snippets/java/build.gradle.kts b/code_snippets/java/build.gradle.kts index 33525235..901cfdde 100644 --- a/code_snippets/java/build.gradle.kts +++ b/code_snippets/java/build.gradle.kts @@ -10,7 +10,7 @@ repositories { mavenCentral() } -val restateVersion = "1.0.1" +val restateVersion = "1.1.1" dependencies { // Restate SDK @@ -21,6 +21,7 @@ dependencies { implementation("dev.restate:sdk-lambda:$restateVersion") implementation("dev.restate:sdk-serde-jackson:$restateVersion") implementation("dev.restate:sdk-request-identity:$restateVersion") + implementation("dev.restate:sdk-testing:$restateVersion") // Jackson parameter names // https://github.com/FasterXML/jackson-modules-java8/tree/2.14/parameter-names @@ -29,6 +30,8 @@ dependencies { implementation("com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.16.1") implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.16.1") + implementation("org.junit.jupiter:junit-jupiter-api:5.11.3") + implementation("dev.restate:sdk-serde-protobuf:$restateVersion") implementation("org.apache.logging.log4j:log4j-core:2.20.0") } diff --git a/code_snippets/java/src/main/java/develop/GreeterTest.java b/code_snippets/java/src/main/java/develop/GreeterTest.java new file mode 100644 index 00000000..1e1d7691 --- /dev/null +++ b/code_snippets/java/src/main/java/develop/GreeterTest.java @@ -0,0 +1,36 @@ +package develop; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import dev.restate.sdk.client.Client; +import dev.restate.sdk.testing.RestateClient; +import dev.restate.sdk.testing.RestateRunner; +import dev.restate.sdk.testing.RestateRunnerBuilder; +import develop.clients.GreeterService; +import develop.clients.GreeterServiceClient; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +class GreeterTest { + + // + @RegisterExtension + private static final RestateRunner RESTATE_RUNNER = + RestateRunnerBuilder.create() + // The service to test + .bind(new GreeterService()) + .buildRunner(); + // + + // + @Test + void testGreet(@RestateClient Client ingressClient) { + // Create the service client from the injected ingress client + var client = GreeterServiceClient.fromClient(ingressClient); + + // Send request to service and assert the response + var response = client.greet("Francesco"); + assertEquals(response, "Hello, Francesco!"); + } + // +} diff --git a/code_snippets/java/src/main/java/develop/clients/GreetCounterObject.java b/code_snippets/java/src/main/java/develop/clients/GreetCounterObject.java index fdfa30f9..71800d7d 100644 --- a/code_snippets/java/src/main/java/develop/clients/GreetCounterObject.java +++ b/code_snippets/java/src/main/java/develop/clients/GreetCounterObject.java @@ -1,4 +1,4 @@ -package operate.invocations; +package develop.clients; import dev.restate.sdk.JsonSerdes; import dev.restate.sdk.ObjectContext; diff --git a/code_snippets/java/src/main/java/develop/clients/GreeterService.java b/code_snippets/java/src/main/java/develop/clients/GreeterService.java index bf18d9a0..6d74e953 100644 --- a/code_snippets/java/src/main/java/develop/clients/GreeterService.java +++ b/code_snippets/java/src/main/java/develop/clients/GreeterService.java @@ -1,4 +1,4 @@ -package operate.invocations; +package develop.clients; import dev.restate.sdk.Context; import dev.restate.sdk.annotation.Handler; diff --git a/code_snippets/java/src/main/java/develop/clients/Ingress.java b/code_snippets/java/src/main/java/develop/clients/Ingress.java index 3ccfd86a..70477bb4 100644 --- a/code_snippets/java/src/main/java/develop/clients/Ingress.java +++ b/code_snippets/java/src/main/java/develop/clients/Ingress.java @@ -1,4 +1,4 @@ -package operate.invocations; +package develop.clients; import dev.restate.sdk.JsonSerdes; import dev.restate.sdk.client.CallRequestOptions; diff --git a/code_snippets/kotlin/build.gradle.kts b/code_snippets/kotlin/build.gradle.kts index a905297e..efcdd304 100644 --- a/code_snippets/kotlin/build.gradle.kts +++ b/code_snippets/kotlin/build.gradle.kts @@ -10,7 +10,7 @@ plugins { repositories { mavenCentral() } -val restateVersion = "1.0.1" +val restateVersion = "1.1.1" dependencies { // Annotation processor @@ -22,6 +22,10 @@ dependencies { implementation("dev.restate:sdk-http-vertx:$restateVersion") implementation("dev.restate:sdk-lambda:$restateVersion") implementation("dev.restate:sdk-request-identity:$restateVersion") + implementation("dev.restate:sdk-testing:$restateVersion") + + implementation("org.junit.jupiter:junit-jupiter-api:5.11.3") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.1") implementation("org.apache.logging.log4j:log4j-core:2.20.0") implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0") diff --git a/code_snippets/kotlin/src/main/kotlin/develop/GreeterTest.kt b/code_snippets/kotlin/src/main/kotlin/develop/GreeterTest.kt new file mode 100644 index 00000000..c7120185 --- /dev/null +++ b/code_snippets/kotlin/src/main/kotlin/develop/GreeterTest.kt @@ -0,0 +1,38 @@ +package develop + +import dev.restate.sdk.client.Client +import dev.restate.sdk.testing.RestateClient +import dev.restate.sdk.testing.RestateRunner +import dev.restate.sdk.testing.RestateRunnerBuilder +import develop.clients.GreeterService +import develop.clients.GreeterServiceClient +import kotlinx.coroutines.test.runTest +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.RegisterExtension + +internal class GreeterTest { + + // + companion object { + @RegisterExtension + private val RESTATE_RUNNER: RestateRunner = + RestateRunnerBuilder.create() + // The service to test + .bind(GreeterService()) + .buildRunner() + } + // + + // + @Test + fun testGreet(@RestateClient ingressClient: Client) = runTest { + // Create the service client from the injected ingress client + val client = GreeterServiceClient.fromClient(ingressClient) + + // Send request to service and assert the response + val response = client.greet("Francesco") + assertEquals(response, "Hello, Francesco!") + } + // +} diff --git a/docs/develop/java/testing.mdx b/docs/develop/java/testing.mdx new file mode 100644 index 00000000..2c1b573c --- /dev/null +++ b/docs/develop/java/testing.mdx @@ -0,0 +1,54 @@ +--- +sidebar_position: 14 +description: "Test your services." +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Testing + +The Java SDK comes with the module `sdk-testing` that integrates with JUnit 5 and TestContainers to start up a Restate container together with your services code and automatically register them. + +```kotlin +implementation("dev.restate:sdk-testing:VAR::JAVA_SDK_VERSION") +``` + +## Using the JUnit 5 Extension + +Given the service to test `GreeterService`, register the JUnit 5 extension that will start Restate along with the service: + + + + ```java + CODE_LOAD::java/src/main/java/develop/GreeterTest.java#extension + ``` + + + ```kotlin + CODE_LOAD::kotlin/src/main/kotlin/develop/GreeterTest.kt#extension + ``` + + + +Note that the extension will start one Restate server for the whole test class. For more details, checkout [`RestateRunner` Javadocs](/javadocs/dev/restate/sdk/testing/RestateRunner.html). + +Once the extension is set, you can implement your test methods as usual, and inject a [`Client`](/javadocs/dev/restate/sdk/client/Client.html) using [`@RestateClient`](/javadocs/dev/restate/sdk/testing/RestateClient.html) to interact with Restate and the registered services: + + + + ```java + CODE_LOAD::java/src/main/java/develop/GreeterTest.java#test + ``` + + + ```kotlin + CODE_LOAD::kotlin/src/main/kotlin/develop/GreeterTest.kt#test + ``` + + + +## Usage without JUnit 5 + +You can use the testing tools without JUnit 5 by creating a [`ManualRestateRunner`](/javadocs/dev/restate/sdk/testing/ManualRestateRunner.html) with [`RestateRunnerBuilder#buildManualRunner`](/javadocs/dev/restate/sdk/testing/RestateRunnerBuilder.html#buildManualRunner()). +For more details, refer to the Javadocs.