Котлинский ленивый блок не выполняется при использовании Mockito и InjectMocks

Я использую Mockito для проверки кода Котлина. Это веб-приложение, и я использую Spring для ввода значений в некоторые поля.

Например, мой фрагмент класса выглядит примерно так:

class MyComponent { @Inject private lateinit var request: HttpServletRequest @Inject private lateinit var database: Database 

Чтобы имитировать это в моем модульном тесте, я использую аннотации @Mock и @InjectMocks от Mockito. Поэтому мой тест выглядит примерно так:

 class MyComponentTest { @Mock private lateinit var request: HttpServletRequest @Mock private lateinit var database: Database @InjectMocks private lateinit var sut: MyComponent @Before fun setup() { MockitoAnnotations.initMocks(this) } 

Что все работает нормально. Однако у меня также есть ленивый блок инициализации в моем компоненте:

 val user: User by lazy { database.findUser() } fun getUsername(): String { return user.name } 

Когда мой тест вызывает myComponent.getUsername() я ожидаю, что database.findUser() будет вызван, поскольку он инициализирует user но этого не происходит.

Если я поставлю точку останова в ленивом блоке, это никогда не ударит. Теперь я предполагаю, что это связано с тем, как Mockito и @InjectMocks должны «касаться» user но я действительно не знаю. Если я сконструирую MyComponent вручную, тогда выполняется ленивый блок, но это не будет вводить мои издевательства.

Как я могу обеспечить, чтобы ленивый блок вызывался правильно из моего теста?

ОБНОВЛЕНИЕ : после недели отсутствия, пытаясь воспроизвести это без каких-либо изменений, и я не мог. Не могу это объяснить.

Я попытался воспроизвести вашу проблему и не смог этого сделать. Этот принцип представляет собой рабочий пример.

Однако я бы рекомендовал пересмотреть способ написания тестов. Рассмотрим следующий пример:

 class MyComponentTest { val request = mock<HttpServletRequest>() val database = mock<Database>() val sut = MyComponent(request, database) @Test fun username() { Mockito.`when`(database.findUser()).thenReturn(User("test")) val username = sut.getUsername() MatcherAssert.assertThat(username, Matchers.equalTo("test")) } } 

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

В случае, если вам интересно, функция вспомогательного помощника – это один лайнер:

 inline fun <reified T : Any> mock() = Mockito.mock(T::class.java) 

В этом контексте можно найти полный обновленный пример.

Intereting Posts
Как преобразовать вывод функции в Unit с Kotlin Запустите AutoBackup вручную из приложения Android. Как исправить «Функция не является частью схемы для этого Царства» в расширении Царского Царства Экземпляр фрагмента сохраняется, но дочерний фрагмент не повторно прикреплен Kotlin – Как сделать делегат недвижимости по карте с пользовательским именем? AndroidAnnotations – ViewById не может использоваться для частного элемента Не удалось запустить программу Kotlin в терминале Как остановить службу уведомления на Android Oreo Создание экземпляра прослушивателя интерфейса в Котлине Есть ли способ открыть URL-адрес в окне Private Window / Ingognito с помощью Java? Kotlin – Как «запоздать» var переопределил интерфейс? Kotlin DSL для создания объектов json (без создания мусора) Весенняя безопасность. Многоязычная страница входа на основе URL Kotlin: Можете ли вы использовать именованные аргументы для varargs? Эффективный коммутатор требует самокритики?