【问题标题】:Kotlin Unit testing - How to mock component of Companion object?Kotlin 单元测试 - 如何模拟 Companion 对象的组件?
【发布时间】:2019-01-18 09:37:51
【问题描述】:

如果我有一个看起来像这样的(简化的)类:

class MyManager @JvmOverloads constructor(/*constructor args*/) : MyManagerInterface {

    @Inject
    lateinit var myLogger: MyLogger

    init {
        component = DaggerLoggerComponent.builder()
                .loggerModule(LoggerModule(internalLogger))
                .build()

        component.inject(this)
    }

    companion object {
        lateinit var component: RemoteLoggerComponent
            private set
    }
}

在单元测试时,我到底如何模拟伴随对象中的组件?

我尝试过使用 Mockito、MockK 等各种技巧,但遇到了一些障碍。

CUT(被测类)是另一个使用 MyManager 组件在其 init 块中注入其依赖项的类,如下所示:

init {
        if(applicationContext == null) {
            throw IllegalStateException("Application Context must not be null")
        } else {

            MyManager.component.inject(this)
        }
    }

基本上,如果注入什么都不做,我会很高兴,因为我可以在外部设置依赖项以进行测试。

感谢所有帮助。包括如果你认为我写错了。我对 Kotlin 和 Dagger 比较陌生。谢谢。

【问题讨论】:

    标签: kotlin mockk


    【解决方案1】:

    基本上,使用 MockK,您需要这样的代码:

    mockkObject(MyManager)
    every { MyManager.component.someOp(...) } returns 5
    

    不确定我是否了解有关注射的所有详细信息。正如你所说,你可以禁用它。

    【讨论】:

    • 天哪!这似乎奏效了。谢谢!我假设 mockkObject 仅用于模拟 kotlin 对象声明。显然不是。
    • 这样使用怎么样:mockkObject(MyManager.Companion) every { MyManager.CompanionsomeOp(...) } returns 5
    • 不适合我。
    【解决方案2】:

    不要忘记取消模拟伴随对象。否则,将在当前测试后使用模拟版本。

    被阻止的模拟应自动为我们取消模拟:

    mockkObject(MyManager) {
      every { MyManager.component.someOp(...) } returns 5
    
      act() 
    
      verify {
        ...
      }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2019-08-22
      • 2020-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-07
      • 2019-12-02
      • 1970-01-01
      相关资源
      最近更新 更多