Micronaut gradle api 测试因查询参数映射到数据类而失败?

问题描述 投票:0回答:1

我有一个运行 micronaut kotlin 应用程序的遗留服务,从基本角度来看,它是功能性的,并且 api 可以按预期运行,无需修改。问题是,当我针对 API 运行 Spek 测试时,请求失败并显示

错误的请求 io.micronaut.http.client.exceptions.HttpClientResponseException:错误请求 在 io.micronaut.http.client.netty.DefaultHttpClient$FullHttpResponseHandler.makeErrorFromRequestBody(DefaultHttpClient.java:2232)

当我通过以下方式点击“测试”API 时的应用程序

http://localhost:{port}/api/v1/test || http://localhost:{port}/api/v1/test?size=1&number=50&sort=ASC
api 正确处理请求。仅当我通过 gradle 测试任务实际运行测试时才会出现该问题。如果我在资源代码中添加调试,它永远不会到达

return HttpResponse.ok(mutableListOf("hello", "world"))

如果我修改api以具有String类型的查询参数

fun listTestValues(@Parameter(required = false, `in` = ParameterIn.QUERY) pagingQuery: String)
调试器确实停在正确的断点处。

最基本形式的代码结构是

interface TestApi {
    fun listTestValues(@Parameter(required = false, `in` = ParameterIn.QUERY) pagingQuery: PagingQueryWS): HttpResponse<List<*>>
}

@Secured(SecurityRule.IS_AUTHENTICATED)
@Controller(
    "/api/v1/test",
    consumes = [MediaType.APPLICATION_JSON],
    produces = [MediaType.APPLICATION_JSON]
)
class TestResource: TestApi {
    @Get("{?pagingQuery*}")
    override fun listTestValues(pagingQuery: PagingQueryWS): HttpResponse<List<*>> {
        return HttpResponse.ok(mutableListOf("hello", "world"))
    }
}

class TestResourceUT: Spek({
    Feature("Test Resource UT") {
        val applicationContext =
            ApplicationContext.builder().build().start()
        val embeddedServer = applicationContext.getBean(EmbeddedServer::class.java).start()
        val client = HttpClient.create(embeddedServer.url)

        Scenario("GET test api") {
            lateinit var returned: List<*>
            When("Responds successfully") {
                val request = HttpRequest.GET<List<String>>("/api/v1/test")
                returned = client
                    .toBlocking()
                    .retrieve(request, List::class.java)
            }
            Then("A List is returned with the found values") {
                assertThat(returned.size).isEqualTo(2)
            }
        }

        afterGroup {
            client.close()
            embeddedServer.close()
        }
    }
})

@Introspected
data class PagingQueryWS(
    override val number: Int = PagingQuery.DEFAULT_PAGE_NUMBER,
    override val size: Int = PagingQuery.DEFAULT_PAGE_SIZE,
    override val sort: String? = null
): PagingQuery

interface PagingQuery {
    val number: Int
    val size: Int
    val sort: String?

    private fun getSort(): Sort {
        return sort
            ?.split(",")
            ?.map {
                val direction = it[0]
                val field = it.substring(1)

                if (direction == '-') {
                    Order.desc(field)
                } else {
                    Order.asc(field)
                }
            }
            ?.let {
                Sort.of(it)
            }
            ?: Sort.UNSORTED
    }

    // External pages are 1-indexed but internal are 0-indexed
    fun toPageable(): Pageable = Pageable.from(number - 1, size, getSort())

    companion object {
        const val DEFAULT_PAGE_SIZE = 50
        const val DEFAULT_PAGE_NUMBER = 1
    }
}

Kotlin 版本:1.9.25 麦克诺版本:3.9.7 斯佩克版本:2.0.7

kotlin gradle micronaut spek
1个回答
0
投票

经过几天的研究,我发现了该问题的解决方案/原因。这取决于单元测试的构建方式。在 TestResourceUT 中有

afterGroup { 
    client.close()
    embeddedServer.close()
}

这是问题的根本原因。我的测试套件有多个测试,这些测试是通过 afterGroup 调用构建的,一旦删除这些测试,测试就全部通过,没有问题。

我无法说出这导致问题的具体原因,但我必须假设测试是同时运行的,并且当嵌入式服务器和 httpClient 为每个测试实例启动时,它们可能共享由client.close() 调用。

© www.soinside.com 2019 - 2024. All rights reserved.