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

已绑定带泛型的Guice实例仍报MissingImplementation?测试中如何获取?

Scala测试中Guice注入泛型类实例的问题

问题场景

在编写Scala测试代码时,尝试通过Guice注入获取带有@Named("producer1")注解的KafkaProducerService[String, String]实例,触发了Guice/MissingImplementation错误,尽管错误提示明确显示该类型的命名绑定已存在。

测试代码如下:

package com.megafarad.play.kafka.module

import com.google.inject.name.Names
import com.megafarad.play.kafka.services.KafkaProducerService
import io.github.embeddedkafka.EmbeddedKafka
import org.apache.kafka.common.serialization.StringDeserializer
import org.scalatest.Assertion
import org.scalatest.concurrent.Eventually
import org.scalatestplus.play.PlaySpec
import org.scalatestplus.play.guice.GuiceOneAppPerTest
import play.api.inject.{BindingKey, QualifierInstance}

import scala.jdk.CollectionConverters._

class TestModuleSpec extends PlaySpec with GuiceOneAppPerTest with EmbeddedKafka with Eventually {

  "TestModule" should {
    "Bind named instances of KafkaProducerService" in {
      withRunningKafka {
        //Arrange
        val producer1 = app.injector.instanceOf(BindingKey(classOf[KafkaProducerService[String, String]],
          Some(QualifierInstance(Names.named("producer1")))))
        val producer2 = app.injector.instanceOf(BindingKey(classOf[KafkaProducerService[String, String]],
          Some(QualifierInstance(Names.named("producer2")))))
        val producer3 = app.injector.instanceOf(BindingKey(classOf[KafkaProducerService[String, String]],
          Some(QualifierInstance(Names.named("producer3")))))

        //Act
        producer1.sendSync("topic1", "key", "value")
        producer2.sendSync("topic2", "key", "value")
        producer3.sendSync("topic3", "key", "value")

        //Assert
        assertMessageCount("topic1", 1)
        assertMessageCount("topic2", 1)
        assertMessageCount("topic3", 1)
      }
    }
  }

  def assertMessageCount(topic: String, count: Int): Assertion = {
    implicit val deserializer: StringDeserializer = new StringDeserializer
    EmbeddedKafka
      .withConsumer[String, String, org.scalatest.Assertion] {
        consumer =>
          consumer.subscribe(Set(topic).asJava)
          eventually {
            assert(consumer.poll(java.time.Duration.ofMillis(1000)).count() == count)
          }
      }
  }
}

错误信息

Guice configuration errors:

1) [Guice/MissingImplementation]: No implementation for KafkaProducerService annotated with @Named("producer1") was bound.

Did you mean?
    * KafkaProducerService<String, String> annotated with @Named("producer1") bound at TestModule.provideProducer1Service(TestModule.scala:74)
      \_ installed by: Modules$OverrideModule -> TestModule

    * KafkaProducerService<String, String> annotated with @Named("producer2") bound at TestModule.provideProducer2Service(TestModule.scala:86)
      \_ installed by: Modules$OverrideModule -> TestModule

    * KafkaProducerService<String, String> annotated with @Named("producer3") bound at TestModule.provideProducer3Service(TestModule.scala:98)
      \_ installed by: Modules$OverrideModule -> TestModule

临时解决办法

注意到错误信息中未显示泛型参数<String, String>,于是创建了继承自KafkaProducerService[String, String]的TestKafkaProducerService类:

package com.megafarad.play.kafka.services

import io.micrometer.core.instrument.MeterRegistry
import play.api.Configuration
import play.api.inject.ApplicationLifecycle

import javax.inject.Inject
import scala.concurrent.ExecutionContext

class TestKafkaProducerService @Inject()(config: Configuration,
                                        producerConfig: Configuration,
                                        metrics: MeterRegistry,
                                        applicationLifecycle: ApplicationLifecycle)(implicit ec: ExecutionContext)
  extends KafkaProducerService[String, String](config, producerConfig, metrics, applicationLifecycle)

将测试中对KafkaProducerService[String, String]的引用替换为TestKafkaProducerService后,测试成功(调整了eventually块的超时时间后)。

核心疑问

是否可以直接在测试中获取带有类型参数的Guice绑定类实例?


内容的提问来源于stack exchange,提问作者Chris Carrington

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 08:53:12