Koin DI Модульное тестирование Android ViewModel

#android #unit-testing #koin

#Android #модульное тестирование #коин

Вопрос:

Я использую Koin DI в своем приложении, и все работает нормально. Я ввел ViewModels без каких-либо проблем.

Например, у меня есть calcViewModel с функцией:

 class CalcViewModel(): ViewModel() {
    fun calculateNumber(): Int{
        var a = 5   3
        return a
    }
}
  

И в приложении я использую его следующим образом:

 class Application : Application() {
    override fun onCreate() {
        super.onCreate()

        startKoin {
        // androidContext(this@MyApp)
        androidLogger(Level.DEBUG)
        androidContext(this@Application)
        modules(
            listOf(
                myModule
            )
        )
    }
  

И в моем файле AppModule:

 val myModule= module {
    viewModel { CalcViewModel() }
}
  

И в приложении, всякий раз, когда мне нужен мой экземпляр ViewModel, я просто использую:

 private val calcViewModel by viewModel<CalcViewModel>()
  

И, как я уже сказал, все работает отлично, но когда я пытаюсь написать простой модульный тест для этой функции

 fun calculateNumber(): Int{
        var a = 5   3
        return a
}
  

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

Это тестовый класс, который я пробовал

 class CalcViewModelTest: KoinTest{

val calcViewModel:CalcViewModel by inject()

@Before
fun setup() {

    startKoin {
        module { single { myModule} }
      
    }
}

@Test
fun calculateNumber(){
    val result = calcViewModel.calculateNumber()  // here I get that error when trying to access calcViewModel var
    Assert.assertEquals(result,8)
}

@After
fun tearDown() {
    stopKoin()
}

}
  

И каждый раз я получаю эту ошибку при попытке запустить свой модульный тест:

 org.koin.core.error.NoBeanDefFoundException: No definition found for 
class:'com.package.CalcViewModel'. Check your definitions!
  

Кроме того, если я использую тот же способ для извлечения ViewModel в тестовом классе, как в приложении:

 val calcViewModel by viewModel<CalcViewModel>()
  

Он использует другой конструктор, который запрашивает 3 параметра (класс, владелец, область видимости)

Я также импортировал в gradle:

 testImplementation "org.koin:koin-androidx-viewmodel:$koin_version"
testImplementation "org.koin:koin-test:$koin_version"
  

Кто — нибудь пробовал писать модульные тесты с помощью Koin и используя ViewModels ?

Спасибо

Комментарии:

1. это должны быть модули, а не модуль

2. @Blackbelt Это просто еще один способ загрузки модулей, если вы используете модуль, как я, вы можете добавить один модуль, если используете модули, он ожидает список модулей. Я тоже пробовал со списком модулей, но безуспешно. В приложении работает отлично, но я не могу его модульно протестировать.

3. в документации сказано использовать modules не module с startKoin . module кажется, нужно объявить (создать) модуль, но у меня нет большого опыта работы с koin

4. @Blackbelt Я просто попробовал тоже самое, просто чтобы быть уверенным на 1000%, startKoin { modules ( listOf( MyModule))} и та же ошибка, что и раньше.

Ответ №1:

Основываясь на документации Koin, вам необходимо использовать by inject() для создания экземпляра класса.

     val calcViewModel by inject<CalcViewModel>()
  

Затем создайте koinTestRule вот так.

     @get:Rule
    val koinTestRule = KoinTestRule.create {
        printLogger()
        modules(myModule)
    }
  

Ответ №2:

В конце концов я просто инициализировал ViewModel и использовал экземпляр.

  private lateinit var viewModel: CalcViewModel
  

и позже в setUp()

 viewModel = CalcViewModel()