Creating a Test for the Echo Service #

Generate the test #

  1. Open 5-ext/ext/src/main/kotlin/demo/echo/EchoService.kt in IntelliJ.
  2. Click within the EchoService class, and then right click and select Generate… and then Test….
  3. In the Create Test dialog window, confirm that the Class name is EchoServiceTest, the Destination package is demo.echo, and check the box next to echoV1.
  4. Click OK to generate a test file in 5-ext/ext/src/test/kotlin/demo/echo/EchoServiceTest.kt.

Create the initial Echo service test structure #

  1. Open the EchoServiceTest.kt file that was created in the previous section.
  2. Add the following code into the existing generated file, and check out the detailed explanation to understand what each section does.
package demo.echo

import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import pragma.PragmaCoreTestFactory
import pragma.ProtoTestFactory
import pragma.SessionTestFactory.playerSession

@ExperimentalCoroutinesApi
internal class EchoServiceTest {
    private val pragmaNode = PragmaCoreTestFactory.pragmaNode()
    private val serviceInstanceId = ProtoTestFactory.serviceInstanceId(0)

    val testObj = EchoService(pragmaNode, serviceInstanceId)

    @Test
    fun echoV1() = runTest {
        val playerSession = playerSession()
    }
}
Method overview

In this code block, we first create the object under the test, and use TestFactories to generate the proper dependencies in the Echo service.

We add the @ExperimentalCoroutinesApi annotation on the test class because Pragma Engine RPC endpoints are suspend functions that require their own coroutine context.

We then replace the stub test function with a more descriptive line to write the test against the echoV1 endpoint. Next, we build the training and trigger the test. All RPC endpoints require a session and a request, so we’re using the SessionTestFactory to make a playerSession.

Create the Echo TestFactory file #

  1. Create a new Kotlin file in the same directory as EchoServiceTest.kt called EchoTestFactory.kt.
  2. Add the following code into the existing generated file, and check out the detailed explanation to understand what each section does.
package demo.echo

object EchoTestFactory {
    fun echoV1Request(i: Int): EchoRpc.EchoV1Request =
        EchoRpc.EchoV1Request.newBuilder().setMessage("message$i").build()

    fun echoV1Response(i: Int): EchoRpc.EchoV1Response =
        EchoRpc.EchoV1Response.newBuilder()
            .setResponseMessage("response: message$i")
            .build()
}
Method overview

We must add the proto creation functions needed for the test. In this case, we create the EchoV1Request and EchoV1Response.

TestFactory functions use an i:Int parameter to provide a seed for the data. Using the same seed results in identical protos of the same type, or complementary protos of different, related types.

In this case, the request has a message and the response has a response:message which match up.

Add the Echo TestFactory to the Echo service test #

  1. Return to the EchoServiceTest.kt file, and add the request and response Echo TestFactory imports.
import demo.echo.EchoTestFactory.echoV1Request
import demo.echo.EchoTestFactory.echoV1Response
  1. Update the @Test with the following code, which adds our request, and then lists the trigger and expectation.
@Test
fun `echoV1 returns the correct message`() = runTest {
    val playerSession = playerSession(1)
    val request = echoV1Request(1)

    val actualResponse = testObj.echoV1(playerSession, request)

    val expectedResponse = echoV1Response(1)
    assertEquals(expectedResponse, actualResponse)
}

Run the Echo service test #

  1. In IntelliJ, right click on EchoServiceTest on the left sidebar.
  2. Select Run ‘EchoServiceTest’ and confirm that the test passes and the build is successfully completed.

Appendix #

You can view the completed source code files for this section here.

5-ext/ext/src/test/kotlin/demo/echo/EchoServiceTest.kt
package demo.echo

import demo.echo.EchoTestFactory.echoV1Request
import demo.echo.EchoTestFactory.echoV1Response
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import pragma.PragmaCoreTestFactory
import pragma.ProtoTestFactory
import pragma.SessionTestFactory.playerSession

@ExperimentalCoroutinesApi
internal class EchoServiceTest {
    private val pragmaNode = PragmaCoreTestFactory.pragmaNode()
    private val serviceInstanceId = ProtoTestFactory.serviceInstanceId(0)

    val testObj = EchoService(pragmaNode, serviceInstanceId)

    @Test
    fun `echoV1 returns the correct message`() = runTest {
        val playerSession = playerSession(1)
        val request = echoV1Request(1)

        val actualResponse = testObj.echoV1(playerSession, request)

        val expectedResponse = echoV1Response(1)
        assertEquals(expectedResponse, actualResponse)
    }

}
5-ext/ext/src/test/kotlin/demo/echo/EchoTestFactory.kt
package demo.echo

object EchoTestFactory {
    fun echoV1Request(i: Int): EchoRpc.EchoV1Request =
        EchoRpc.EchoV1Request.newBuilder().setMessage("message$i").build()

    fun echoV1Response(i: Int): EchoRpc.EchoV1Response =
        EchoRpc.EchoV1Response.newBuilder()
            .setResponseMessage("response: message$i")
            .build()
}