如何在单元测试中通过@ProvidesIntoSet注入Set类型依赖?
问题分析
你遇到的核心问题是测试中手动实例化了A对象,而Guice的injectMembers(this)只负责注入测试类ATest本身的成员,不会处理你手动new出来的objectUnderTest的成员。另外,你的Modules里的getSomeHandler依赖SomeHandler,测试模块中没有提供SomeHandler的绑定,Guice无法创建对应的IHandlers实例加入集合。
解决方案
下面提供两种可行的修复方式:
方式一:让Guice负责创建A对象
放弃手动new A,改为通过Guice注入A的实例,这样Guice会自动处理所有成员注入:
class ATest { private val dependency1 = mockk<Dependency1>(relaxed = true) private val dependency2 = mockk<Dependency2>(relaxed = true) private val mockSomeHandler = mockk<SomeHandler>(relaxed = true) // 让Guice注入A的实例 @Inject private lateinit var objectUnderTest: A protected var injector: Injector = Guice.createInjector(object : AbstractModule() { override fun configure() { // 绑定A的构造参数依赖 bind(Dependency1::class.java).toInstance(dependency1) bind(Dependency2::class.java).toInstance(dependency2) // 绑定SomeHandler的mock实例 bind(SomeHandler::class.java).toInstance(mockSomeHandler) // 安装你的模块 install(Modules()) } }) @BeforeEach fun setup() { injector.injectMembers(this) } @Test fun `some test`() { // 此时objectUnderTest.handlersSet应该不为null,包含mock的SomeHandler对应的IHandlers实例 assertNotNull(objectUnderTest.handlersSet) } }
方式二:手动注入A的成员
如果坚持手动实例化A,需要调用Guice的injectMembers方法注入A的成员,同时确保模块中绑定了SomeHandler:
class ATest { private val dependency1 = mockk<Dependency1>(relaxed = true) private val dependency2 = mockk<Dependency2>(relaxed = true) private val mockSomeHandler = mockk<SomeHandler>(relaxed = true) private lateinit var objectUnderTest: A protected var injector: Injector = Guice.createInjector(object : AbstractModule() { override fun configure() { // 绑定SomeHandler的mock实例 bind(SomeHandler::class.java).toInstance(mockSomeHandler) install(Modules()) } }) @BeforeEach fun setup() { objectUnderTest = A(dependency1, dependency2) // 关键:让Guice注入A的成员 injector.injectMembers(objectUnderTest) } @Test fun `some test`() { assertNotNull(objectUnderTest.handlersSet) } }
关键注意点
- 必须在测试模块中绑定
SomeHandler的实例(通常是mock),否则Guice无法执行getSomeHandler方法来生成IHandlers实例,handlersSet依然会是null。 - 不要混合手动实例化和Guice注入,要么全交给Guice创建,要么手动调用
injectMembers处理实例的成员注入。
内容的提问来源于stack exchange,提问作者xyzzz
相关产品推荐
相关产品推荐

