如何测试委托属性的生成器?

How do I test generators for delegated properties?

在我当前的项目中有一个 class 稍后将由许多其他人实现。 class 为委托属性提供了一些生成器。

abstract class BaseClass {
    protected val delegated1 get() = new Delegated1Impl()
    protected val delegated2 get() = new Delegated2Impl()
    ...
}

这个基础class可以这样使用:

class Example : BaseClass() {
    var field1 by delegated1
    var field2 by delegated2
}

现在我想测试这些委托生成器。其中一些包含我想测试的逻辑,但现在我只想知道每次调用它们时都是 return 一个新实例。

现在我的问题是:如何测试这些生成器?
生成器在扩展 classes 之外是不可见的,所以我不能简单地创建它的实例并调用这些方法。

@Test
fun `delegated1 should always return a new instance`() {
    val target = object: BaseClass()

    val first = target.delegated1    // This does not work since it is protected
    val second = target.delegated1

    assertTrue(first !== second)
}

每当您 "call" get 方法时,您都需要创建一个新对象。那么如何测试呢?使用 提供者

A Provider<T> 只是一个为您提供具体 class 新实例的对象。它的签名是这样的:

interface Provider<T> {
    fun get() : T
}

所以你需要在你的BaseClass中注入一个新的Provider<T>:

abstract class BaseClass(
        private val implementation1Provider : Provider<YourInterface>,
        private val implementation2Provider : Provider<YourInterface>) {
    protected val delegated1 get() = implementation1Provider.get()
    protected val delegated2 get() = implementation2Provider.get()
    ...
}

现在您可以在测试中注入您的自定义提供程序并断言它们已被调用:

@Test
fun `delegated1 should always return a new instance`() {
    val implementation1Provider = ...
    val target = Example(implementation1Provider, ...)

    val first = target.field1

    // assert that implementation1Provider.get() has been called
}