TW AppTest
Tegral Web AppTest is a simple and straight-forward integration/end-to-end testing library for Tegral Web applications.
Package name | Catalog dependency | Full Gradle name |
---|---|---|
tegral-web-apptest | tegralLibs.web.apptest | guru.zoroark.tegral:tegral-web-apptest:VERSION |
Note that, while AppTest may seem similar to Controllers tests on the surface, but they have a few fundamental differences:
- Controller tests are made for lightweight testing that does not require much else other than a pre-setup Ktor environment.
- Controller tests follow the "test subject" pattern, whereas integration tests do not provide direct access to the controllers
- Controller tests are built with mocking in mind, which is not the case of integration tests.
- AppTest tests allow installation of special features to abstract away complicated test setups that may occur with databases, Ktor, etc.
- AppTest automatically starts and stops services
Writing a test
Let's say that we have a module that contains all of our application's components.
class GreetingService {
fun greet(who: String?): String = "Hello World!"
}
class GreetingController(scope: InjectionScope) : KtorController() {
private val service: GreetingService by scope()
override fun Routing.install() {
get("/greet") {
call.respond(service.greet())
}
}
}
val appModule = tegralDiModule {
put(::GreetingService)
put(::GreetingController)
}
Tests with AppTest are written by subclassing the TegralWebIntegrationTest
class:
class ExampleTest : TegralWebIntegrationTest({
// Integration test AppDSL-like block
}) {
// ...
}
You can then add features, modules, etc. in the block provided to the TegralWebIntegrationTest constructor:
class ExampleTest : TegralWebIntegrationTest({
put(appModule)
}) {
// ...
}
Then, add tests using the test
function. Here's an example of a test for the /greet
endpoint in our example:
class ExampleTest : TegralWebIntegrationTest({
put(appModule)
}) {
@Test
fun `greet endpoint test without arguments`() = test {
// ...
}
}
Within the test
block, you have access to the client
object that allows you to send HTTP requests to your client, just like you would with a regular Ktor client.
class ExampleTest : TegralWebIntegrationTest({
put(appModule)
}) {
@Test
fun `greet endpoint test without arguments`() = test {
val result = client.get("/greet").body<Greeting>()
assertEquals(Greeting("hello", "world"), result)
}
}
Configuring the client
You can further configure the client as you see fit by using the createClient
function.
class ExampleTest : TegralWebIntegrationTest({
put(appModule)
}) {
@Test
fun `greet endpoint test without arguments`() = test {
val customClient = createClient(null) { // null is because we want the default app
// Configure your client here
// See https://ktor.io/docs/create-client.html#configure-client
}
// ...
}
}