0

I'm toying around with a small ktor webapp where I want to split functionality in multiple modules. I have a root module where I install the features I want to use throughout the whole application

fun Application.rootModule(testing: Boolean = false) {
    install(ContentNegotiation) {
        gson {
        }
    }
....

and a domain module where I'm implementing domain functionality

fun Application.bookModule() {

    routing {
        get("/books/{id}") {
          ....
        }
    }
}

Now I want to implement a test for this functionality

class BookControllerTests: StringSpec({

    "get should return correct book"{
        withTestApplication({bookModule()}) {
            val testCall: TestApplicationCall = handleRequest(method = HttpMethod.Get, uri = "/books/42") {
            }
            testCall.response.status() shouldBe HttpStatusCode.OK
        }
    }

})

If I run it like this, I get the error message Response pipeline couldn't transform 'class org.codeshards.buecherkiste.book.domain.Book' to the OutgoingContent - so content negotiation is not working. Which makes sense since this is installed in the root module which is not called here. I solved this problem by wrapping the root module and the domain module in a test module that is implemented along my test case:

fun Application.bookModuleTest() {
    rootModule()
    bookModule()
}

and this now seems to work.

Since I'm a noob when ktor and kotest are concerned I'd like to ask for feedback on this solution. Is this a proper way to do what I want or am I setting myself up for trouble down the line? Is there a better solution?

1 Answers1

1

Yes, this is a proper way to test an application because modules don't depend on each other and are bound via configuration. Also, instead of adding one more extension method for Application, you can introduce the following helper function just for testing:

fun <T> testApp(test: TestApplicationEngine.() -> T): T {
    return withTestApplication(
        {
            rootModule()
            bookModule()
        }, 
        test
    )
}
Aleksei Tirman
  • 4,658
  • 1
  • 5
  • 24