#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
кажется, нужно объявить (создать) модуль, но у меня нет большого опыта работы с koin4. @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()