kotlin 将函数限制为仅对测试可见

f1tvaqid  于 2023-03-03  发布在  Kotlin
关注(0)|答案(1)|浏览(141)

假设我有一些方法想用于单元测试,但是我想阻止它们在生产代码中使用,那么我如何才能使在生产代码中使用函数变得尽可能困难,而不求助于任何可能被SecurityManager阻止的反射技巧(例如修改函数的可见性)?
从本质上讲,我是否可以创建类似@VisibleForTesting的东西,但在其背后有一些强制措施,或者模拟Rust unit tests的封装能力,可以直接嵌入到他们正在测试的模块中,从而允许测试访问该模块中的项,而不要求这些项在模块外部可见?

6uxekuva

6uxekuva1#

您可以通过利用@RequiresOptIn注解来实现这一点,它的一个预期用途是“不应在声明库之外使用,但由于技术原因而公开的内部声明”,尽管在本例中,声明应该是private,但由于技术原因它是internal
首先,您创建一个注解,它具有一个令人讨厌的冗长的特定名称。

@RequiresOptIn(message = "This part of the API is visible only for testing.")
internal annotation class VisibleForTestingOnly_DoNotUseInProductionCode

然后,用该注解来注解只用于测试的函数,这样,每当您试图使用该函数而没有显式选择使用只用于测试的代码时,就会得到编译时错误。

class Foo {
    fun bar() {
        // ...
    }

    @VisibleForTestingOnly_DoNotUseInProductionCode
    internal fun leakSomeImplementationDetails(): LeakyInternalState {
        // ...
    }
}

最后,在应该使用这个函数的测试中,将opt-in注解添加到相关的文件/类/函数中。

@OptIn(VisibleForTestingOnly_DoNotUseInProductionCode::class)
class FooTest {
    // ...
}

有些人仍然可以在生产代码中使用这个注解,但是现在的工作量要大得多,因为您必须显式地选择使用一个类名,告诉您不要这样做,并且您的代码审阅者(您确实有代码审阅者,对吗?)将很容易地发现这个注解在生产代码中的不当使用。

...但是整个模块范围内的选择加入怎么样?

不幸的是,这个选项对您来说仍然是一个可用的工具,但是为org.mylibrary.VisibleForTestingOnly_DoNotUseInProductionCode添加一个模块范围的选择性加入对于任何代码审阅者来说仍然是相当可疑的(您仍然有我们前面提到的代码审阅者,对吗?)

相关问题