Можно ли использовать Mockito с Kotlin без открытия класса?
Как мы, наверное, знаем, по умолчанию класс Kotlin, определенный после его определения, является окончательным, если он явно не объявлен open
.
Это вызовет вызов, когда мы захотим его использовать, используя Mockito. Нам нужно явно объявить его как open
. Есть ли способ, которым мы могли бы избежать объявления его как open
, в то время как он мог бы Mock его для нашего тестирования?
Ответы
Ответ 1
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
Ответ 2
Есть три способа узнать, как вы можете издеваться над классами Kotlin:
-
Используйте интерфейсы вместо классов. В этом случае вы заменяете все обычаи определенного класса соответствующим интерфейсом. И в тестировании кода вы обманываете интерфейс.
interface Something { /* ... */ }
class SomethingImpl : Something { /* ... */ }
fun processSomething(something: Something) { /* ... */ }
val something = mock(Something::class.java)
processSomething(mock)
-
Сделать классы открытыми, что не очень удобно.
-
Используйте PowerMock вместо Mockito. Используя ClassLoader
, вы можете сделать гораздо больше, чем с помощью Mockito.
Я предпочитаю первый подход, потому что неплохо работать с интерфейсами вместо классов, даже если вы не используете насмешливые фреймворки.
Ответ 3
Плагин MockMaker, похоже, не работает при запуске тестов эспрессо. Таким образом, вы можете использовать Kotlin all-open pugin.
Добавьте плагин в 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