是否可以在没有开课的情况下使用Mockito和Kotlin?

Ely*_*lye 12 unit-testing mocking mockito kotlin

我们可能知道,默认情况下,Kotlin类一旦定义,它就是最终的,除非它被明确声明open.

当我们想要使用Mockito进行模拟时,这会发出挑战.我们需要明确地声明它open.有没有办法可以避免将其声明为open能够模拟它进行测试?

Lov*_*vis 9

Mockito2现在也可以模拟最终的类.

但是,此功能是选择加入,因此您需要手动启用它.
为此,您需要定义/mockito-extensions/org.mockito.plugins.MockMaker包含该行的文件mock-maker-inline

参见例如
http://hadihariri.com/2016/10/04/Mocking-Kotlin-With-Mockito/https://github.com/mockito/mockito/wiki/What%27s-new-in-Mockito-2 #unmockable
快速介绍

在旁注,这目前不适用于Android

  • 不幸的是,它似乎没有用. (2认同)

Cri*_*tan 9

运行espresso测试时,MockMaker插件似乎不起作用.因此,您可以使用Kotlin的全开pugin代替.

在build.gradle中添加插件:

buildscript {
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-allopen:$kotlin_version"
    }
}

apply plugin: "kotlin-allopen"
Run Code Online (Sandbox Code Playgroud)

指定将使类打开的注释:

allOpen {
    annotation("com.my.MyMockable")
}
Run Code Online (Sandbox Code Playgroud)

创建可用于注释类的注释:

@Target(AnnotationTarget.CLASS)
annotation class MyMockable
Run Code Online (Sandbox Code Playgroud)

然后,为了使您的类及其公共方法Mockable(打开),请使用您的注释对其进行注释:

@MyMockable
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢这个解决方案,因为它是最少侵入性的,并且是对替代方案提供最多控制的解决方案。 (2认同)

Mic*_*ael 8

有三种方法我知道如何模拟Kotlin类:

  1. 使用接口而不是类.在这种情况下,您将使用相应的接口替换特定类的所有用法.在测试代​​码中,您可以模拟界面.

    interface Something { /* ... */ }
    
    class SomethingImpl : Something { /* ... */ }
    
    fun processSomething(something: Something) { /* ... */ }
    
    val something = mock(Something::class.java)
    processSomething(mock)
    
    Run Code Online (Sandbox Code Playgroud)
  2. 打开课程,这不是很方便.

  3. 使用PowerMock而不是Mockito.使用它ClassLoader可以比Mockito做得更多.

我更喜欢第一种方法,因为即使你不使用模拟框架,使用接口而不是类也是一个好主意.

  • 没有正当理由(从OO或API设计角度)创建单独的界面是过度工程,因为它只会增加复杂性.这甚至比让课堂不必要地"打开"更糟糕.(并且,不,不创建接口不*违反GoF的原则"程序到接口,而不是实现".) (5认同)
  • 这个问题太笼统,没有一个正确的答案,但在我看来,需要模拟的类通常作为依赖项注入,并注入其他依赖项。在这种情况下,为此类类创建单独的接口是一个好主意,因为它有助于使系统松散耦合并使单元测试更容易甚至成为可能。这对我来说是一个非常正当的理由。 (2认同)
  • 它有点偏离主题但是想指出使用接口并不一定会减少耦合.你总是依赖合同.如果只是将所有公共方法移动到接口,则不会影响耦合,只需制作更多代码行.一个类有一个接口+实现,但是当你传递一个对象时,它只是所有依赖的接口(__ contract_). (2认同)