代码之家  ›  专栏  ›  技术社区  ›  Archie G. Quiñones

基于Arrow KT的依赖注入

  •  0
  • Archie G. Quiñones  · 技术社区  · 6 年前

    Arrow Kt Documentation on Dependency Injection Activity 或者 Fragment . 所以给出的例子如下:

    import Api.*
    
    class SettingsActivity: Activity {
      val deps = FetcherDependencies(Either.monadError(), ActivityApiService(this))
    
      override fun onResume() {
        val id = deps.createId("1234")
    
        user.text =
          id.fix().map { it.toString() }.getOrElse { "" }
    
        friends.text =
          deps.getUserFriends(id).fix().getOrElse { emptyList() }.joinToString()
      }
    }
    

    但现在我在想 SettingsActivity unit tested ? 因为依赖关系是在活动中创建的,所以不能再为测试而更改它?

    当使用其他 Dependency Injection Dagger ,一个 Module @Inject 用于“注入”模块内定义的依赖项。所以现在当单元测试 活动 ,我只需要定义一个不同的模块或手动将依赖项的值设置为一个模拟对象。

    0 回复  |  直到 6 年前
        1
  •  2
  •   El Paco    6 年前

    在Dagger中,您将创建一个模拟或测试类 @Inject 而不是 ActivityApiService . 这里也一样。

    而不是:

    class ActivityApiService(val ctx: Context) {
      fun createId(): String = doOtherThing(ctx)
    }
    

    你知道吗

    interface ActivityApiService {
      fun createId(): String
    }
    

    现在有两个实现,一个用于prod

    class ActivityApiServiceImpl(val ctx: Context): ActivityApiService {
      override fun createId(): Unit = doOtherThing(ctx)
    }
    

    另一个用于测试

    fun testBla() {
      val api =  object: ActivityApiService {
        override fun createId(): String = "4321"
      }
    
      val deps = FetcherDependencies(Either.monadError(), api)
    
      deps.createId("1234") shouldBe "4321"
    }
    

    甚至可以使用Mockito或类似的工具来创建

    我有几篇关于如何在Android框架之外进行解耦和统一测试的文章,它们与Arrow无关。检查 'Headless development in Fully Reactive Apps' 以及相关项目 https://github.com/pakoito/FunctionalAndroidReference

    如果您的依赖关系图变得太复杂,并且您需要一些编译时魔法来创建这些依赖关系,那么您可以在测试和应用程序中创建一个本地类 @注入

    推荐文章