Łukasz Bednarczyk
08/23/2021, 12:22 PMResponse has already been sent
io.ktor.server.engine.BaseApplicationResponse$ResponseAlreadySentException: Response has already been sent
but only in tests and only in the situation when I call
every { something, something } throws AnyException
Did you have similar problem?Łukasz Bednarczyk
08/23/2021, 12:30 PMAleksei Tirman [JB]
08/23/2021, 1:40 PMŁukasz Bednarczyk
08/23/2021, 1:53 PMclass AudioFilesHandlerTest : DescribeSpec(), KoinTest {
private val deviceAuthenticationService = mockk<DeviceAuthenticationService>()
init {
startKoin {
modules(
module {
single { deviceAuthenticationService }
})
}
describe("AudioFilesHandler") {
val audioFilesUri = "/api/audio-files"
describe(audioFilesUri) {
describe("when device auth params are missing") {
it("should returns status 400") {
withApplication(apiTestEnv) {
val call = handleRequest(uri = audioFilesUri, method = <http://HttpMethod.Post|HttpMethod.Post>) {
val boundary = "WebAppBoundary"
addHeader(ContentType, FormData.withParameter("boundary", boundary).toString())
}
call.response.status() shouldBe HttpStatusCode.BadRequest
}
}
}
describe("when device is unregistered") {
val product = createProduct()
val device = createDevice(product = product)
every {
deviceAuthenticationService.challenge(product.productId, device.deviceId)
} throws DeviceAuthenticationException()
it("should returns 401") {
withApplication(apiTestEnv) {
val call = handleRequest(uri = audioFilesUri, method = <http://HttpMethod.Post|HttpMethod.Post>) {
val boundary = "WebAppBoundary"
addHeader(ContentType, FormData.withParameter("boundary", boundary).toString())
addHeader("productId", product.productId)
addHeader("deviceId", device.deviceId)
}
call.response.status() shouldBe HttpStatusCode.Unauthorized
}
}
}
}
}
}
}
Łukasz Bednarczyk
08/23/2021, 1:54 PMinstall(StatusPages) {
exception<DeviceAuthenticationException> {
call.respond(HttpStatusCode.Unauthorized)
}
exception<UnsupportedDeviceException> {
call.respond(HttpStatusCode.Forbidden)
}
}
Aleksei Tirman [JB]
08/23/2021, 2:23 PMResponseAlreadySentException
.Łukasz Bednarczyk
08/23/2021, 2:28 PMŁukasz Bednarczyk
08/23/2021, 2:31 PMResponse has already been sent
io.ktor.server.engine.BaseApplicationResponse$ResponseAlreadySentException: Response has already been sent
at io.ktor.server.engine.BaseApplicationResponse.commitHeaders(BaseApplicationResponse.kt:47)
at io.ktor.server.engine.BaseApplicationResponse.respondOutgoingContent$suspendImpl(BaseApplicationResponse.kt:143)
at io.ktor.server.engine.BaseApplicationResponse.respondOutgoingContent(BaseApplicationResponse.kt)
at io.ktor.server.testing.TestApplicationResponse.respondOutgoingContent(TestApplicationResponse.kt:113)
at io.ktor.server.engine.BaseApplicationResponse$Companion$setupSendPipeline$1.invokeSuspend(BaseApplicationResponse.kt:320)
at io.ktor.server.engine.BaseApplicationResponse$Companion$setupSendPipeline$1.invoke(BaseApplicationResponse.kt)
at io.ktor.server.engine.BaseApplicationResponse$Companion$setupSendPipeline$1.invoke(BaseApplicationResponse.kt)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:248)
at io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:116)
at io.ktor.util.pipeline.SuspendFunctionGun.proceedWith(SuspendFunctionGun.kt:126)
at io.ktor.server.engine.DefaultTransformKt$installDefaultTransformations$1.invokeSuspend(DefaultTransform.kt:35)
at io.ktor.server.engine.DefaultTransformKt$installDefaultTransformations$1.invoke(DefaultTransform.kt)
at io.ktor.server.engine.DefaultTransformKt$installDefaultTransformations$1.invoke(DefaultTransform.kt)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:248)
at io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:116)
at io.ktor.util.pipeline.SuspendFunctionGun.proceedWith(SuspendFunctionGun.kt:126)
at io.ktor.server.engine.DefaultTransformKt$installDefaultTransformations$1.invokeSuspend(DefaultTransform.kt:35)
at io.ktor.server.engine.DefaultTransformKt$installDefaultTransformations$1.invoke(DefaultTransform.kt)
at io.ktor.server.engine.DefaultTransformKt$installDefaultTransformations$1.invoke(DefaultTransform.kt)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:248)
at io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:116)
at io.ktor.util.pipeline.SuspendFunctionGun.execute(SuspendFunctionGun.kt:136)
at io.ktor.util.pipeline.Pipeline.execute(Pipeline.kt:79)
at com.vascoelectronics.ApiKt$configureAPI$4$1.invokeSuspend(Api.kt:112)
at com.vascoelectronics.ApiKt$configureAPI$4$1.invoke(Api.kt)
at com.vascoelectronics.ApiKt$configureAPI$4$1.invoke(Api.kt)
at io.ktor.features.StatusPages.interceptCall(StatusPages.kt:107)
at io.ktor.features.StatusPages.access$interceptCall(StatusPages.kt:18)
at io.ktor.features.StatusPages$interceptCall$1.invokeSuspend(StatusPages.kt)
(Coroutine boundary)
at io.ktor.server.engine.DefaultTransformKt$installDefaultTransformations$1.invokeSuspend(DefaultTransform.kt:35)
at io.ktor.server.engine.DefaultTransformKt$installDefaultTransformations$1.invokeSuspend(DefaultTransform.kt:35)
at com.vascoelectronics.ApiKt$configureAPI$4$1.invokeSuspend(Api.kt:112)
at io.ktor.features.StatusPages.interceptCall(StatusPages.kt:107)
at io.ktor.features.StatusPages$Feature$install$2.invokeSuspend(StatusPages.kt:142)
at io.ktor.features.CallLogging$Feature$install$2.invokeSuspend(CallLogging.kt:139)
at io.ktor.server.testing.TestApplicationEngine$callInterceptor$1.invokeSuspend(TestApplicationEngine.kt:296)
at io.ktor.server.testing.TestApplicationEngine$2.invokeSuspend(TestApplicationEngine.kt:50)
at io.ktor.server.testing.TestApplicationEngine$handleRequest$pipelineJob$1.invokeSuspend(TestApplicationEngine.kt:295)
at io.ktor.server.testing.TestApplicationEngine$handleRequest$1.invokeSuspend(TestApplicationEngine.kt:153)
at io.kotest.core.internal.TestCaseExecutor$executeAndWait$4$1$1$3$1$1.invokeSuspend(TestCaseExecutor.kt:234)
at io.kotest.core.internal.TestCaseExecutor$executeAndWait$4$1$1$3$1.invokeSuspend(TestCaseExecutor.kt:233)
at io.kotest.engine.ExecutorExecutionContext$executeWithTimeoutInterruption$4.invokeSuspend(ExecutorExecutionContext.kt:77)
at io.kotest.core.internal.TestCaseExecutor$executeAndWait$4$1$1$3.invokeSuspend(TestCaseExecutor.kt:232)
at io.kotest.mpp.ReplayKt.replay(replay.kt:18)
at io.kotest.core.internal.TestCaseExecutor$executeAndWait$4$1$1.invokeSuspend(TestCaseExecutor.kt:227)
at io.kotest.engine.ExecutorExecutionContext$executeWithTimeoutInterruption$4.invokeSuspend(ExecutorExecutionContext.kt:77)
at io.kotest.core.internal.TestCaseExecutor$executeAndWait$4$1.invokeSuspend(TestCaseExecutor.kt:220)
at io.kotest.core.internal.TestCaseExecutor$executeAndWait$4.invokeSuspend(TestCaseExecutor.kt:219)
at io.kotest.core.internal.TestCaseExecutor.invokeTestCase(TestCaseExecutor.kt:184)
at io.kotest.core.internal.TestCaseExecutor.executeActiveTest(TestCaseExecutor.kt:153)
at io.kotest.core.internal.TestCaseExecutor$intercept$innerExecute$1$1.invokeSuspend(TestCaseExecutor.kt:89)
at io.kotest.core.internal.TestCaseExecutor.executeIfEnabled(TestCaseExecutor.kt:117)
at io.kotest.core.internal.TestCaseExecutor$intercept$innerExecute$1.invokeSuspend(TestCaseExecutor.kt:89)
at io.kotest.core.internal.TestCaseExecutor.execute(TestCaseExecutor.kt:69)
at io.kotest.engine.spec.runners.SingleInstanceSpecRunner.runTest(SingleInstanceSpecRunner.kt:104)
at com.vascoelectronics.api.handlers.AudioFilesHandlerTest$2$1$2.invokeSuspend(AudioFilesHandlerTest.kt:63)
at io.kotest.core.spec.style.scopes.DescribeSpecContainerContext$containerTest$2.invokeSuspend(DescribeSpecContainerContext.kt:99)
at io.kotest.core.internal.ExecutionsKt$executeWithBehaviours$2$1.invokeSuspend(executions.kt:13)
at io.kotest.core.internal.ExecutionsKt.wrapTestWithGlobalAssert(executions.kt:39)
at io.kotest.core.internal.ExecutionsKt$executeWithBehaviours$2.invokeSuspend(executions.kt:12)
at io.kotest.core.internal.TestCaseExecutor$executeInScope$2.invokeSuspend(TestCaseExecutor.kt:268)
at io.kotest.core.internal.TestCaseExecutor$executeAndWait$4$1$1.invokeSuspend(TestCaseExecutor.kt:223)
at io.kotest.engine.ExecutorExecutionContext$executeWithTimeoutInterruption$4.invokeSuspend(ExecutorExecutionContext.kt:77)
at io.kotest.core.internal.TestCaseExecutor$executeAndWait$4$1.invokeSuspend(TestCaseExecutor.kt:220)
at io.kotest.core.internal.TestCaseExecutor$executeAndWait$4.invokeSuspend(TestCaseExecutor.kt:219)
at io.kotest.core.internal.TestCaseExecutor.invokeTestCase(TestCaseExecutor.kt:184)
at io.kotest.core.internal.TestCaseExecutor.executeActiveTest(TestCaseExecutor.kt:153)
at io.kotest.core.internal.TestCaseExecutor$intercept$innerExecute$1$1.invokeSuspend(TestCaseExecutor.kt:89)
at io.kotest.core.internal.TestCaseExecutor.executeIfEnabled(TestCaseExecutor.kt:117)
at io.kotest.core.internal.TestCaseExecutor$intercept$innerExecute$1.invokeSuspend(TestCaseExecutor.kt:89)
at io.kotest.core.internal.TestCaseExecutor.execute(TestCaseExecutor.kt:69)
at io.kotest.engine.spec.runners.SingleInstanceSpecRunner.runTest(SingleInstanceSpecRunner.kt:104)
at com.vascoelectronics.api.handlers.AudioFilesHandlerTest$2$1.invokeSuspend(AudioFilesHandlerTest.kt:56)
at io.kotest.core.spec.style.scopes.DescribeSpecContainerContext$containerTest$2.invokeSuspend(DescribeSpecContainerContext.kt:99)
at io.kotest.core.internal.ExecutionsKt$executeWithBehaviours$2$1.invokeSuspend(executions.kt:13)
at io.kotest.core.internal.ExecutionsKt.wrapTestWithGlobalAssert(executions.kt:39)
at io.kotest.core.internal.ExecutionsKt$executeWithBehaviours$2.invokeSuspend(executions.kt:12)
at io.kotest.core.internal.TestCaseExecutor$executeInScope$2.invokeSuspend(TestCaseExecutor.kt:268)
at io.kotest.core.internal.TestCaseExecutor$executeAndWait$4$1$1.invokeSuspend(TestCaseExecutor.kt:223)
at io.kotest.engine.ExecutorExecutionContext$executeWithTimeoutInterruption$4.invokeSuspend(ExecutorExecutionContext.kt:77)
at io.kotest.core.internal.TestCaseExecutor$executeAndWait$4$1.invokeSuspend(TestCaseExecutor.kt:220)
at io.kotest.core.internal.TestCaseExecutor$executeAndWait$4.invokeSuspend(TestCaseExecutor.kt:219)
at io.kotest.core.internal.TestCaseExecutor.invokeTestCase(TestCaseExecutor.kt:184)
at io.kotest.core.internal.TestCaseExecutor.executeActiveTest(TestCaseExecutor.kt:153)
at io.kotest.core.internal.TestCaseExecutor$intercept$innerExecute$1$1.invokeSuspend(TestCaseExecutor.kt:89)
at io.kotest.core.internal.TestCaseExecutor.executeIfEnabled(TestCaseExecutor.kt:117)
at io.kotest.core.internal.TestCaseExecutor$intercept$innerExecute$1.invokeSuspend(TestCaseExecutor.kt:89)
at io.kotest.core.internal.TestCaseExecutor.execute(TestCaseExecutor.kt:69)
at io.kotest.engine.spec.runners.SingleInstanceSpecRunner.runTest(SingleInstanceSpecRunner.kt:104)
at com.vascoelectronics.api.handlers.AudioFilesHandlerTest$2.invokeSuspend(AudioFilesHandlerTest.kt:42)
at io.kotest.core.spec.style.scopes.DescribeSpecRootContext$test$1.invokeSuspend(DescribeSpecRootContext.kt:71)
at io.kotest.core.internal.ExecutionsKt$executeWithBehaviours$2$1.invokeSuspend(executions.kt:13)
at io.kotest.core.internal.ExecutionsKt.wrapTestWithGlobalAssert(executions.kt:39)
at io.kotest.core.internal.ExecutionsKt$executeWithBehaviours$2.invokeSuspend(executions.kt:12)
at io.kotest.core.internal.TestCaseExecutor$executeInScope$2.invokeSuspend(TestCaseExecutor.kt:268)
at io.kotest.core.internal.TestCaseExecutor$executeAndWait$4$1$1.invokeSuspend(TestCaseExecutor.kt:223)
at io.kotest.engine.ExecutorExecutionContext$executeWithTimeoutInterruption$4.invokeSuspend(ExecutorExecutionContext.kt:77)
at io.kotest.core.internal.TestCaseExecutor$executeAndWait$4$1.invokeSuspend(TestCaseExecutor.kt:220)
at io.kotest.core.internal.TestCaseExecutor$executeAndWait$4.invokeSuspend(TestCaseExecutor.kt:219)
at io.kotest.core.internal.TestCaseExecutor.invokeTestCase(TestCaseExecutor.kt:184)
at io.kotest.core.internal.TestCaseExecutor.executeActiveTest(TestCaseExecutor.kt:153)
at io.kotest.core.internal.TestCaseExecutor$intercept$innerExecute$1$1.invokeSuspend(TestCaseExecutor.kt:89)
at io.kotest.core.internal.TestCaseExecutor.executeIfEnabled(TestCaseExecutor.kt:117)
at io.kotest.core.internal.TestCaseExecutor$intercept$innerExecute$1.invokeSuspend(TestCaseExecutor.kt:89)
at io.kotest.core.internal.TestCaseExecutor.execute(TestCaseExecutor.kt:69)
at io.kotest.engine.spec.runners.SingleInstanceSpecRunner.runTest(SingleInstanceSpecRunner.kt:104)
at io.kotest.engine.spec.runners.SingleInstanceSpecRunner$execute$interceptAndRun$2$4.invokeSuspend(SingleInstanceSpecRunner.kt:57)
at io.kotest.engine.launchers.SequentialTestLauncher$launch$3$1$1.invokeSuspend(SequentialTestLauncher.kt:22)
Łukasz Bednarczyk
08/23/2021, 2:33 PMAleksei Tirman [JB]
08/23/2021, 2:43 PMŁukasz Bednarczyk
08/23/2021, 3:07 PMŁukasz Bednarczyk
08/23/2021, 3:22 PMŁukasz Bednarczyk
08/23/2021, 5:11 PMwithApplication(apiTestEnv)
calls are shared. In the Ktor code base withTestApplication
is called without parameters so a test environment is created for each call.