为什么单元测试不需要 Hilt,但 UI 测试却需要?

问题描述 投票:0回答:2

Hilt 测试指南文档有这段关于单元测试的内容

Hilt 对于单元测试来说不是必需的,因为在测试使用构造函数注入的类时,不需要使用 Hilt 来实例化该类。相反,您可以通过传入假或模拟依赖项来直接调用类构造函数,就像构造函数没有注释一样:

@ActivityScoped
class AnalyticsAdapter @Inject constructor(
  private val service: AnalyticsService
) { ... }

class AnalyticsAdapterTest {

  @Test
  fun `Happy path`() {
    // You don't need Hilt to create an instance of AnalyticsAdapter.
    // You can pass a fake or mock AnalyticsService.
    val adapter = AnalyticsAdapter(fakeAnalyticsService)
    assertEquals(...)
  }
}

但是这里你可以看到文档正在解释如何在UI测试中使用Hilt。

我的问题是为什么 Hilt 对于单元测试不是必需的,但对于 UI 测试却是必需的?

android unit-testing dependency-injection ui-testing dagger-hilt
2个回答
1
投票

通过单元测试,您可以验证类内部的行为,而在 UI 测试中,您可以验证给定数据的 UI 状态。在单元测试中,您不需要 Hilt 来生成对象树,您正在测试应用程序的一个小型构建单元,一个类,一个函数。您的单元测试所需的对象范围有限,因此这是您不需要 Hilt 在每个单元测试中构建整个对象树的另一个原因。

在单元测试中,您验证事件是否已发生、函数是否已被调用或给定输入返回结果。

Hilt 在您的 UI 测试中注入假组件,您可以通过这些组件提供渲染的数据。


0
投票

我同意这里写的关于已接受答案的评论

单元测试中的单元没有被广泛接受的定义,它不一定必须为单个类或少量类编写,而是可以为可以跨越的功能/用例编写大量的课程。 @suyash

以下是具体操作方法。

为了能够对功能/用例进行“单元测试”,您仍然可以使用 Hilt 的设置,而无需运行 Hilt 并生成图表。

例如:

  • 模块 A 有一个测试来验证用例,但该用例是用模块 B 中的类注入的。

  • 模块B中的那个类实际上是一个接口加上一个内部类实现。所以你不能直接实例化它。

模块B代码:

interface MyInterface {}

internal class MyObjectFromB() : MyInterface {}

还有模块B的刀柄设置:

@Module
@InstallIn(SingletonComponent::class)
object MyBModule {

    @Provides
    fun provideMyInterface(): MyInterface = MyObjectFromB()

}

在模块 A 中,您想要执行以下操作:

@Test
fun `some test`() {
    assertTrue( MyObjectFromA(MyObjectFromB()).foo() )
}

但是

MyObjectFromB
internal
到 ModuleB,所以从 ModuleA 你不能,但这并不能阻止你自己使用模块类(
MyBModule
):

@Test
fun `some test`() {
    assertTrue( MyObjectFromA(MyBModule.provideMyInterface()).foo() )
}

我并不是说它完美:-),但它允许您进行集成测试样式的单元测试,同时避免运行 Hilt 并保持模块封装

© www.soinside.com 2019 - 2024. All rights reserved.