Во-первых, мне очень нравится читать блог о Stylingandroid.com и всем рекомендую. Часто (или в большинстве случаев) есть действительно крутые трюки, функции или руководства по Android и программированию в целом.

Что бы ни. В прошлую пятницу (он всегда ведет блог в пятницу) он написал статью о Kotlin Testability. Я тест-наркоман, так что название звучит действительно обещанным мне. К сожалению, это не так.

1. mock-maker-inline

Он упомянул об этом в последней части статьи. Проблема в том, что методы/классы/свойства Kotlin по умолчанию являются окончательными. Это означает, что вы не можете легко издеваться над этими типами с помощью Mockito по умолчанию. Но помощь есть. Mockito предлагает вариант (не ребята из JetBrains, Марк 😉), чтобы изменить его с помощью mock-maker-inline.

Я действительно не рекомендую это. Это просто сильно замедляет ваши тесты! Я не знаю почему. Может быть, это из-за подклассов (что бы это ни значило). Но я только что сделал опыт, что это медленно.

Тестирование должно быть максимально быстрым. В противном случае вы будете раздражены длительными тестами и, в конце концов, решите просто не тестировать…

Другие решения:
* JetBrains предоставляет необязательный allOpen plugin, который делает методы/классы/свойства и т. д. не окончательными, если они объявлены с аннотацией.
* Используйте внедрение зависимостей, как он описал в своей статье

2. Фабрика, которая является синглтоном

Чтобы решить свою проблему, он должен создать фабрику.
Конечно, это фабрика по замыслу. Но это не фабрика с точки зрения Котлина.
Эта фабрика является Singleton.

Только потому, что в Kotlin легко создавать синглтоны, не стоит ими злоупотреблять!

Другое (Kotlin) решение:
* Используйте companion object вместо Singleton.

Резюме:

Он использует — также мой рекомендуемый способ — внедрение зависимостей (или лучше: внедрение конструктора), но делает конструктор видимым только для классов пакетов. Это не что иное, как наличие такого в Java:

public DateStringProvider() {
  this(new DefaultFactory());
}
@VisibleForTesting(otherwise = VisibleForTesting.NONE) 
DateStringProvider(Factory factory) {
  mFactory = factory
}

Это правильный способ сделать это, и я (или, может быть, вы тоже?!) уже делаю это, верно?! 😉