Search code examples
kotlinktorktor-client

How to provide an HttpClient to ktor server from the outside to facilitate mocking external services?


I am trying to provide an HttpClient from the outside to my ktor server so that I can mock external services and write tests, however I get this exception when I run my test:

Please make sure that you use unique name for the plugin and don't install it twice. Conflicting application plugin is already installed with the same key as `Compression`
io.ktor.server.application.DuplicatePluginException: Please make sure that you use unique name for the plugin and don't install it twice. Conflicting application plugin is already installed with the same key as `Compression`
    at app//io.ktor.server.application.ApplicationPluginKt.install(ApplicationPlugin.kt:112)
    at app//com.example.plugins.HTTPKt.configureHTTP(HTTP.kt:13)
    at app//com.example.ApplicationKt.module(Application.kt:14)
    at app//com.example.ApplicationTest$expected to work$1$1.invoke(ApplicationTest.kt:39)
    at app//com.example.ApplicationTest$expected to work$1$1.invoke(ApplicationTest.kt:38)

and thats a bit unexpected to me because I am not applying the Compression plugin twice as far as I can tell. If I run the server normally and manually call my endpoint with curl then it works as expected. What am I doing wrong?

I added a runnable sample project here with a failing test.


Solution

  • The problem is that you have the application.conf file and by default, the testApplication function tries to load modules which are enumerated there. Since you also explicitly load them in the application {} block the DuplicatePluginException occurs. To solve your problem you can explicitly load an empty configuration instead of the default one:

    // ...
    application {
        module(client)
    }
    
    environment {
        config = MapApplicationConfig()
    }
    // ...