Intereting Posts
Передача данных в BroadcastReceiver из PendingIntent (AlarmManager) андроид, получивший манифест слияния с ошибкой после обновления до новой версии gradle Есть ли способ получить поведение FixedTreadPool с помощью сопрограмм? FusedLocationProviderClient С сервисом Android Kotlin Определение размера для настраиваемого типа массива в Android Kotlin Android Studio 3.0 Proguard с использованием kotlin & greendao возвращает ClassLookupException Spring Data Neo4j 5's EntityScan содержит сопутствующие объекты при использовании Kotlin Почему некоторые методы настройки Java автоматически становятся свойствами Kotlin, а некоторые нет? Как импортировать пакеты Java в Kotlin Native Как решить: «ошибка: не удается найти класс символов …» после преобразования класса Java в Kotlin? Установка текста в EditText Kotlin, Android Какая версия Dokka идет с какой версией Kotlin? Kotlin: разрешить общее наследование TreeWalker не работает с Kotlin / Gradle? Intellij IDEA не показывает доступные предложения для ресурсов Android в файлах Kotlin

Как насмехаться над объектом Singleton Kotlin?

Учитывая объект Singleton Kotlin и удовольствие, которое вызывает его метод

object SomeObject { fun someFun() {} } fun callerFun() { SomeObject.someFun() } 

Есть ли способ SomeObject.someFun() вызов SomeObject.someFun() ?

    Просто сделайте объект реализацией интерфейса, чем вы можете издеваться над объектом с любой насмешливой библиотекой. Вот пример Junit + Mockito + Mockito-Kotlin :

     import com.nhaarman.mockito_kotlin.mock import com.nhaarman.mockito_kotlin.whenever import org.junit.Assert.assertEquals import org.junit.Test object SomeObject : SomeInterface { override fun someFun():String { return "" } } interface SomeInterface { fun someFun():String } class SampleTest { @Test fun test_with_mock() { val mock = mock<SomeInterface>() whenever(mock.someFun()).thenReturn("42") val answer = mock.someFun() assertEquals("42", answer) } } , import com.nhaarman.mockito_kotlin.mock import com.nhaarman.mockito_kotlin.whenever import org.junit.Assert.assertEquals import org.junit.Test object SomeObject : SomeInterface { override fun someFun():String { return "" } } interface SomeInterface { fun someFun():String } class SampleTest { @Test fun test_with_mock() { val mock = mock<SomeInterface>() whenever(mock.someFun()).thenReturn("42") val answer = mock.someFun() assertEquals("42", answer) } } 

    Или в случае, если вы хотите mock SomeObject внутри callerFun :

     import com.nhaarman.mockito_kotlin.mock import com.nhaarman.mockito_kotlin.whenever import org.junit.Assert.assertEquals import org.junit.Test object SomeObject : SomeInterface { override fun someFun():String { return "" } } class Caller(val someInterface: SomeInterface) { fun callerFun():String { return "Test ${someInterface.someFun()}" } } // Example of use val test = Caller(SomeObject).callerFun() interface SomeInterface { fun someFun():String } class SampleTest { @Test fun test_with_mock() { val mock = mock<SomeInterface>() val caller = Caller(mock) whenever(mock.someFun()).thenReturn("42") val answer = caller.callerFun() assertEquals("Test 42", answer) } } , import com.nhaarman.mockito_kotlin.mock import com.nhaarman.mockito_kotlin.whenever import org.junit.Assert.assertEquals import org.junit.Test object SomeObject : SomeInterface { override fun someFun():String { return "" } } class Caller(val someInterface: SomeInterface) { fun callerFun():String { return "Test ${someInterface.someFun()}" } } // Example of use val test = Caller(SomeObject).callerFun() interface SomeInterface { fun someFun():String } class SampleTest { @Test fun test_with_mock() { val mock = mock<SomeInterface>() val caller = Caller(mock) whenever(mock.someFun()).thenReturn("42") val answer = caller.callerFun() assertEquals("Test 42", answer) } } 

    Недостаточно манипулировать байтовым кодом, ответ – нет, если вы не хотите и не можете изменить код. Самый простой способ (и способ, который я рекомендовал бы), чтобы callerFun вызов SomeObject.someFun() для SomeObject.someFun() , должен обеспечить некоторый способ SomeObject.someFun() его макет объекта.

    например

     object SomeObject { fun someFun() {} } fun callerFun() { _callerFun { SomeObject.someFun() } } internal inline fun _callerFun(caller: () -> Unit) { caller() } 

    Идея здесь состоит в том, чтобы изменить то, что вы готовы изменить. Если вы уверены, что хотите один синглтон и функцию верхнего уровня, действующие на этом синглетоне, то один из способов, как было продемонстрировано выше, сделать функцию верхнего уровня проверкой без изменения ее публичной подписи – перенести ее реализацию на internal функцию что позволяет скользить макет.