已绑定带泛型的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
相关产品推荐
相关产品推荐

