Kotest MockServer

MockServer provides a virtual HTTP server. With this library, you can test as if communicating with a real server without using a separate mocking library such as mockk.

Kotest provides an extension for integration with the MockServer library.

MockServer

MockServer provides a virtual HTTP server. With this library, you can test as if communicating with a real server without using a separate mocking library such as mockk.

Kotest provides an extension for integration with the MockServer library.

Adding the Dependency

To use MockServer, add the io.kotest.extensions:kotest-extensions-mockserver module as a dependency. You can check the latest version on Maven Central.

testImplementation("io.kotest.extensions:kotest-extensions-mockserver:<version>")

Configuration

With a mock server, you can define an in-process HTTP server with hard-coded responses for the paths you want to test.

To use it in Kotest, attach a MockServerListener instance to the spec under test, and Kotest automatically controls its lifecycle.

Connecting the Mock Server

Then you only need to connect responses using MockServerClient.

For example:

class MyMockServerTest : FunSpec() {
  init {

      // this attaches the server to the lifeycle of the spec
      listener(MockServerListener(1080))

      // we can use the client to create routes. Here we are setting them up
      // before each test by using the beforeTest callback.
      beforeTest {
         MockServerClient("localhost", 1080).`when`(
            HttpRequest.request()
               .withMethod("POST")
               .withPath("/login")
               .withHeader("Content-Type", "application/json")
               .withBody("""{"username": "foo", "password": "bar"}""")
         ).respond(
            HttpResponse.response()
               .withStatusCode(202)
               .withHeader("X-Test", "foo")
         )
      }

      // this test will confirm the endpoint works
      test("login endpoint should accept username and password json") {

         // using the ktor client to send requests
         val client = HttpClient(CIO)
         val resp = client.post<io.ktor.client.statement.HttpResponse>("http://localhost:1080/login") {
            contentType(ContentType.Application.Json)
            body = """{"username": "foo", "password": "bar"}"""
         }

         // these handy matchers come from the kotest-assertions-ktor module
         resp.shouldHaveStatus(HttpStatusCode.Accepted)
         resp.shouldHaveHeader("X-Test", "foo")
      }
  }
}

The example above is, of course, only testing the mock itself, but it shows how a real test could be structured. For example, if you have an API client you want to test, you can use the mock server to configure API routes, then call methods on the API client and verify that the response is handled correctly.


References