Arrow KT上的依赖项注入



在Arrow Kt依赖项注入文档中,依赖项在"世界边缘"定义,或者在Android中可以是ActivityFragment。因此,给出的例子如下:

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来"注入"模块内部定义的依赖项。因此,现在在对Activity进行单元测试时,我只需要定义一个不同的模块,或者手动将依赖项的值设置为mock对象。

在Dagger中,您将创建一个Mock或Test类,它将是@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或类似工具来创建CCD_ 12。

我有几篇关于如何在Android框架之外解耦和统一的文章,这些文章与Arrow无关。检查"全反应应用程序中的无头开发"和相关项目https://github.com/pakoito/FunctionalAndroidReference.

如果依赖关系图变得过于复杂,并且您想要一些编译时魔法来创建这些依赖关系,那么您总是可以在测试中创建一个本地类,并在那里创建@Inject构造函数。重点是与不可统一的东西脱钩,比如整个Android框架:D

相关内容

  • 没有找到相关文章

最新更新