Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Mockito.mock什么时候创建部分mock而不是“mock”;全称;嘲弄_Java_Kotlin_Mockito_Partial Mocks - Fatal编程技术网

Java Mockito.mock什么时候创建部分mock而不是“mock”;全称;嘲弄

Java Mockito.mock什么时候创建部分mock而不是“mock”;全称;嘲弄,java,kotlin,mockito,partial-mocks,Java,Kotlin,Mockito,Partial Mocks,鉴于此代码: // Subject.kt open class Subject(var x: Int) { constructor(): this(42) { println("made it") } fun doit() { x += 1 println("did it: $x") } } 运行makeit时,输出为: Is mock: true Is spy: false did it: 1 did i

鉴于此代码:

// Subject.kt

open class Subject(var x: Int) {

    constructor(): this(42) {
        println("made it")
    }

    fun doit() {
        x += 1
        println("did it: $x")
    }
}
运行
makeit
时,输出为:

Is mock: true
Is spy:  false
did it: 1
did it: 2
这似乎表明正在创建主题的某些实例,但绕过了潜在的关键构造函数逻辑。这与“部分模拟”是一致的,但是代码没有做任何事情来请求这样的事情

我发现这是一个令人惊讶的默认行为,因为文档都强烈警告不要使用部分模拟。我一直找不到描述
mock()
何时返回部分mock的文档,因此无法确定如何从类中获取“完整mock”

因此:

  • Mockito.mock()何时创建部分模拟
  • Mockito能为一个类创建一个“完全模拟”吗?还是仅仅为了一个界面
  • 如何申请“完全模拟”

翻阅源代码,通过反复试验,我得出以下结论:

  • 当模拟类时,Mockito创建类的ByteBuddy生成的子类的实例,而不调用构造函数=>all member data是默认值
  • 打开方法(Java的默认方法;在Kotlin中用
    Open
    声明):
    • 默认情况下不调用,并返回返回类型的默认值
    • 当(…)配置为
      时将调用。然后调用realmethod()
    • 如果使用
      defaultAnswer
      设置为
      CALLS\u REAL\u方法创建模拟,将调用
  • final
    方法无法重写=>它们将正常调用,但它们将看到所有成员数据的默认值
  • 因此,似乎所有类模拟都是部分模拟,但由于Java中的默认方法是开放的,因此它们通常看起来像常规模拟。默认情况下,它们实际上是常规模拟

    这在Kotlin中很快就会出现,因为默认情况下方法是
    final


    知道这是如何工作的,可以减少处理类mock时的挫败感

    我会将
    返回1
    解释为该类未被模拟的标志。(检查您是否看到
    println
    )如果它在模拟的位置,它应该返回
    0
    。(除非在kotlin中有所不同)。部分所有mock都是使用
    spy
    创建的。我更新了这个问题,以显示Mockito报告该类已被mock。我还向
    doit
    添加了第二个调用,以显示“mock”处于保留状态。我认为这种行为可能与
    kotlin
    不兼容,因此我将其添加为标记。您是否尝试过其他模拟库(
    mockitokotlin
    mockk
    )?@second:Doh!我们在Java中看到了类似的行为(这就是促使调查的原因)。但是可以肯定的是,上面代码的Java版本创建了预期的模拟。我会写一份更好的报告。谢谢如果您有一个导致问题的java示例,请随意添加一个新问题,包括一个。
    Is mock: true
    Is spy:  false
    did it: 1
    did it: 2