Издевательский интерфейс с Kotlin и Mockito

Я действительно не понимаю интерфейс, насмешливый в Котлине. Я не уверен, что это конкретный Kotlin или относится к java. До сих пор я только пробовал это в Котлине.

У меня есть класс с интерфейсами:

val mockObj = mock(MyClass::class.java, withSettings().extraInterfaces(IMyInterface::class.java) 

теперь это вызывает следующую проблему в IntelliJ:

 `when`(mockObj.someMethod()).thenReturn(0.1) 

someMethod() будет красным (я предполагаю, что это зависит от цветовой схемы, но вы получаете идею – проблема: неразрешенная ссылка )

для этого я просто включаю эту строку:

 val mockInterface = mockObj as IMyInterface 

mockInterface будет серым подчеркнуто подчеркнутым, потому что он никогда не используется . Я все еще использую mockObj для

однако это приводит к красному исчезновению

Я не уверен, почему это работает … может кто-нибудь объяснить теорию?

чтобы избавиться от серого подчеркивания, я затем val mockInterface =

поэтому моя магическая линия сводится к mockObj as IMyInterface

Возвращаемый тип mock(MyClass::class.java) – это MyClass . Возвращенный объект также является экземпляром IMyInterface, так как вы попросили Mockito, но компилятор Kotlin не может этого знать.

mockObj as IMyInterface сообщает компилятору Kotlin, чтобы он приводил mockObj в IMyInterface. Поскольку компилятор Kotlin поддерживает умные приведения , он знает, что если эта строка не вызывает каких-либо исключений, то mockObj является экземпляром IMyInterface. И таким образом вы можете вызвать someMethod() и вставить для вас необходимый бросок.

Вы можете воспроизвести это более простым примером:

 val foo: Any = "hello" val bar = foo as String println(foo.length) // smart cast added here 

Вы также можете использовать оператор is чтобы заставить компилятор вставить умный листинг

 val foo: Any = "hello" if (foo is String) { println(foo.length) // smart cast added here }