Можно ли использовать Mockito с Kotlin без открытия класса?

Как мы, наверное, знаем, по умолчанию класс Kotlin, определенный после его определения, является окончательным, если он явно не объявлен open .

Это вызовет вызов, когда мы захотим сделать Mock с помощью Mockito. Нам нужно явно объявить его open . Есть ли способ, которым мы могли бы избежать объявления его как open то время как он мог бы Mock его для нашего тестирования?

Mockito2 теперь может также имитировать финальные классы.

Однако эта функция включена , поэтому вам нужно включить ее вручную.
Для этого вам необходимо определить файл /mockito-extensions/org.mockito.plugins.MockMaker содержащий строку mock-maker-inline

См. Например,
http://hadihariri.com/2016/10/04/Mocking-Kotlin-With-Mockito/ или https://github.com/mockito/mockito/wiki/What%27s-new-in-Mockito-2#unmockable
для быстрого введения

на стороне примечание, это в настоящее время не работает для android

Есть три способа, которыми я знаю, как вы можете издеваться над классами Kotlin:

  1. Используйте интерфейсы вместо классов. В этом случае вы заменяете все обычаи определенного класса соответствующим интерфейсом. И в тестировании кода вы издеваетесь над интерфейсом.

     interface Something { /* ... */ } class SomethingImpl : Something { /* ... */ } fun processSomething(something: Something) { /* ... */ } val something = mock(Something::class.java) processSomething(mock) 
  2. Сделайте классы открытыми, что не очень удобно.

  3. Используйте PowerMock вместо Mockito. Используя свой ClassLoader вы можете сделать гораздо больше, чем с Mockito.

Я предпочитаю первый подход, потому что неплохо работать с интерфейсами вместо классов, даже если вы не используете насмешливые фреймворки.

Плагин MockMaker, похоже, не работает при запуске тестов эспрессо. Таким образом, вы можете использовать полностью открытый Pugin Kotlin .

Добавьте плагин в build.gradle:

 buildscript { dependencies { classpath "org.jetbrains.kotlin:kotlin-allopen:$kotlin_version" } } apply plugin: "kotlin-allopen" 

Укажите аннотацию, которая сделает класс открытым:

 allOpen { annotation("com.my.MyMockable") } 

Создайте свою аннотацию, которая может использоваться для аннотирования классов:

 @Target(AnnotationTarget.CLASS) annotation class MyMockable 

Затем, чтобы сделать свой класс и его общедоступные методы Mockable (открытыми), аннотировать его с помощью аннотации:

 @MyMockable