Вместо использования инициализатора, используйте вспомогательное (личное) свойство и используйте get()
для val
, который нужно смоделировать:
private val _theVal = Foo()
val theVal get() = _theVal
Использование геттера вместоИнициализатор создает метод получения без статического поля поддержки.Вы можете проверить байт-код, чтобы увидеть это:
Kotlin:
package com.example
@JvmField // See also: https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html#instance-fields
val thisIsAField = "I'm static!"
val thisIsAValWithInitialiser = "I'm a static field too!"
val thisIsAValWithGetter get() = "I'm hardcoded in the getter method!"
Байт-код (я удалил большую часть беспорядка, чтобы мою точку зрения было легче увидеть):
public final static Ljava/lang/String; thisIsAField
private final static Ljava/lang/String; thisIsAValWithInitialiser
public final static getThisIsAValWithInitialiser()Ljava/lang/String;
L0
LINENUMBER 6 L0
GETSTATIC com/example/FooBarTestKt.thisIsAValWithInitialiser : Ljava/lang/String;
ARETURN
L1
public final static getThisIsAValWithGetter()Ljava/lang/String;
L0
LINENUMBER 8 L0
LDC "I'm hardcoded in the getter method!"
ARETURN
L1
static <clinit>()V
L0
LINENUMBER 4 L0
LDC "I'm static!"
PUTSTATIC com/example/FooBarTestKt.thisIsAField : Ljava/lang/String;
L1
LINENUMBER 6 L1
LDC "I'm a static field too!"
PUTSTATIC com/example/FooBarTestKt.thisIsAValWithInitialiser : Ljava/lang/String;
RETURN
Что вы можете увидеть здесь?Между thisIsAField
и thisIsAValWithInitialiser
есть важное сходство, заключающееся в том, что они поддерживаются статическими полями.Метод получения thisIsAValWithInitialiser
просто возвращает это значение.Значение равно private
.
Сходство между thisIsAValWithInitialiser
и thisIsAValWithGetter
состоит в том, что они оба являются публичными методами получения, но разница в том, что возвращаемое значение thisIsAValWithGetter
жестко закодировано в теле метода,Это просто публичный метод, который MockK может переопределить (хотя он и является окончательным).
Я предполагаю (как я не знаю внутреннее устройство), что MockK не может отменять GETSTATIC com/example/FooBarTestKt.thisIsAValWithInitialiser : Ljava/lang/String;
, поэтому val
инициализатор не может быть посмешищем.