繁体   English   中英

@MockK 或 mockk()

[英]@MockK or mockk()

使用 Mockk 进行 Android 单元测试时,声明依赖项时使用符号有什么区别?

class Test {
    private val x: X = mockk()

    private val test = TestClass(x)
...
}

或者

class Test {
    @MockK
    private lateinit var x: X

    @InjectMockKs
    private lateinit var test: TestClass
    
    @Before
    fun setup() {
        MockKAnnotations.init(this)
    }
...
}

由于以下两个原因,我建议在测试中使用mockk()和“天真的”构造函数依赖项注入而不是注释:

  1. mockk()构建器允许您使用val定义不可变变量,这更安全、高效且更好*(就软件开发而言),而对于@Mockk ,您应该使用var关键字;

  2. @InjectMockKs并不像看起来那么酷。 我在一个项目中发现了与 Mockito 相同的问题。 我的队友删除了构造函数 arguments 中间某处的 class 依赖项之一,构建并运行代码,但忘记在本地修复并运行测试。 他推动了这些更改,但随后我们在“运行测试”管道阶段遇到了一个错误,该错误指向任何地方,只是 NPE 关于丢失 class。我们花了一些额外的时间终于找到了问题,问题是

Mockito 将尝试仅通过构造函数注入、属性注入或 setter 注入来注入模拟,如下所述。 如果以下任何策略失败,则 Mockito不会报告失败 也就是说,您必须自己提供依赖项。

https://www.javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/InjectMocks.html

来自MockK 项目

不,这两种实现之间没有区别,它们是等价的。

一般来说,当您需要在代码中动态声明模拟时,您可以使用 mockk(),或者例如,如果您需要一个模拟来放松其单元功能(在这种情况下,您可以使用 mockk(relaxUnitFun =真)。

如果您的模拟具有所有相同的行为,则可以使用注释版本。

如果你的 TestClass 的依赖会改变,使用 Annotation 会更好。

因为你只需要再添加/删除一个@MockK ,不需要关心目标类的构造函数。

原来的

@ExtendWith(MockKExtension::class)
class Test {
    @MockK
    private lateinit var x: X

    @InjectMockKs
    private lateinit var test: TestClass
}

TestClass添加一个依赖项

@ExtendWith(MockKExtension::class)
class Test {
    @MockK
    private lateinit var x: X

    @MockK
    private lateinit var y: Y  // <1> Just add this

    @InjectMockKs
    private lateinit var test: TestClass  // <2> Don't need to add the changed dependency into it's constructor
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM