Параметр, заданный как ненулевой, имеет значение NULL при использовании Mokito anyObject () для функции Kotlin

Мой код, как показано ниже, со ссылкой на решение в https://stackoverflow.com/a/30308199/3286489

import org.mockito.Mock import org.mockito.Mockito import org.mockito.MockitoAnnotations import org.mockito.Mockito.* class SimpleClassTest { private fun <T> anyObject(): T { Mockito.anyObject<T>() return uninitialized() } private fun <T> uninitialized(): T = null as T lateinit var simpleObject: SimpleClass @Mock lateinit var injectedObject: InjectedClass @Before fun setUp() { MockitoAnnotations.initMocks(this) } @Test fun testSimpleFunction() { simpleObject = SimpleClass(injectedObject) verify(injectedObject).settingDependentObject(anyObject()) } } 

У меня все еще есть ошибка ниже

 java.lang.IllegalArgumentException: Parameter specified as non-null is null: method my.package.InjectedClass.settingDependentObject, parameter dependentObject 

Я что-то пропустил?

ОБНОВЛЕНО Ниже приведенный код (простейшая форма и работа)

 class SimpleClass(val injectedClass: InjectedClass) { fun simpleFunction() { injectedClass.settingDependentObject(DependentClass(Response.Builder().build())) } } open class DependentClass(response: Response) { } open class InjectedClass() { lateinit var dependentObject: DependentClass fun settingDependentObject(dependentObject: DependentClass) { this.dependentObject = dependentObject } } 

По умолчанию классы и члены Kotlin являются окончательными . Мокито не может высмеять финальные классы или методы . Таким образом, когда вы пишете:

 verify(injectedObject).settingDependentObject(anyObject()) 

вызывается реальная реализация, которая требует непустого аргумента.

Чтобы исправить это, откройте свой класс и метод или, что еще лучше, измените SimpleClass чтобы принять интерфейс в качестве аргумента конструктора и вместо этого SimpleClass интерфейс.

Существует проект, специально предназначенный для решения проблемы с закрытым по умолчанию Kotlin в модульном тестировании с Mockito. Для JUNIT вы можете использовать kotlin-testrunner, который является простым способом сделать любой тест Kotlin автоматически открывать классы для тестирования, поскольку они загружаются загрузчиком классов. Использование простое, просто добавьте одну аннотацию @RunWith(KotlinTestRunner::class) , например:

 @RunWith(KotlinTestRunner::class) class MyKotlinTestclass { @Test fun test() { ... } } 

Это подробно освещено в статье. Никогда не говорите финала: насмешливые классы Котлина в модульных тестах

Это автоматически охватывает ваш прецедент, позволяя всем классам высмеиваться, что в противном случае было бы запрещено.