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

如何在单元测试中通过@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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 04:35:46