You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin Quarkus应用Kafka测试阶段遭遇SRMSG18304错误:未知通道dial-out排查求助

解决Quarkus Kafka测试中"Unknown channel dial-out"错误

看起来你在Quarkus集成Kafka的测试中遇到了通道识别问题,我来帮你分析下原因并给出解决方案:

问题诊断

你的错误根源在于模拟对象与真实测试组件的冲突,具体有两个关键点:

  1. MockK Emitter覆盖了通道配置:你用@MockK注解了Emitter,这会让MockK生成一个模拟实例,完全替代了Quarkus通过InMemoryConnector创建的真实Emitter。这就导致你的InMemoryConnector配置的dial-out通道根本没有被使用,自然会提示"未知通道"。
  2. 手动创建InMemoryConnector实例无效:测试类里你自己new了InMemoryConnector,但Quarkus测试环境中已经有一个由框架管理的、关联了你的application.yml配置的实例,手动创建的实例和它完全无关,无法读取到你的通道配置。

解决方案

1. 修改测试类:移除MockK Emitter,注入框架管理的InMemoryConnector

把测试类里的MockK Emitter去掉,改用依赖注入获取Quarkus已经配置好的InMemoryConnector,这样就能正确关联到你的dial-out通道:

import com.abnamro.ddc.pigeon.domain.core.models.events.ClassificationFinishedEvent
import io.quarkus.test.common.QuarkusTestResource
import io.quarkus.test.junit.QuarkusTest
import io.smallrye.reactive.messaging.providers.connectors.InMemoryConnector
import io.smallrye.reactive.messaging.providers.connectors.InMemorySink
import org.junit.jupiter.api.Test
import javax.inject.Inject

@QuarkusTest
@QuarkusTestResource(KafkaTestResourceLifecycleManager::class)
internal class CaptureCaseCompletedTopicPublisherTest {

    @Inject
    lateinit var topicPublisher: CaptureCaseCompletedTopicPublisher

    // 注入Quarkus管理的InMemoryConnector实例,它已经关联了你的application.yml配置
    @Inject
    lateinit var connector: InMemoryConnector

    // 可以手动创建事件实例,或者如果有生产者的话也可以注入
    private val classificationFinishedEvent = ClassificationFinishedEvent(/* 填充你的事件字段 */)

    @Test
    internal fun `A proper ClassificationFinishedEvent should return a successful response`() {
        // 获取配置好的dial-out通道的Sink
        val outgoingSink: InMemorySink<ClassificationFinishedEvent> = connector.sink("dial-out")
        
        // 调用发送方法
        topicPublisher.send(classificationFinishedEvent)
        
        // 验证消息是否成功发送到通道
        assert(outgoingSink.received().size == 1)
        assert(outgoingSink.received()[0].payload() == classificationFinishedEvent)
    }
}

2. 确保Publisher类正确绑定通道

检查你的CaptureCaseCompletedTopicPublisher类,必须通过@Channel注解明确指定要使用的通道名称,确保和配置文件里的dial-out一致:

import com.abnamro.ddc.pigeon.domain.core.models.events.ClassificationFinishedEvent
import org.eclipse.microprofile.reactive.messaging.Channel
import org.eclipse.microprofile.reactive.messaging.Emitter
import javax.inject.Inject

class CaptureCaseCompletedTopicPublisher {

    // 必须指定@Channel注解,绑定到dial-out通道
    @Inject
    @Channel("dial-out")
    lateinit var emitter: Emitter<ClassificationFinishedEvent>

    fun send(event: ClassificationFinishedEvent) {
        emitter.send(event)
    }
}

3. 可选:简化生命周期管理器

由于你已经在application.yml的%test环境中配置了smallrye-in-memory连接器,其实你的生命周期管理器可以简化(甚至移除),因为配置已经会自动生效。如果保留的话,确保它的通道名称和配置完全一致即可。

额外排查点

  • 检查application.yml的%test配置是否被正确加载:可以在测试中打印配置值,或者查看Quarkus启动日志中是否有加载测试环境配置的信息。
  • 确认所有地方的通道名称完全一致:dial-out的拼写、大小写在配置文件、@Channel注解、测试代码中必须完全相同,不能有空格或拼写错误。

内容的提问来源于stack exchange,提问作者Ricardo de Vries

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 21:43:13