This is exactly one of the reasons why the view model is passed with a default value. In the preview, you can pass a test object:
@Preview
@Composable
private fun HomeScreenPreview() {
val viewModel = HomeViewModel()
// setup viewModel as you need it to be in the preview
HomeScreen(viewModel = viewModel, navigateToDetailsAction = {}, openCardDetailsAction = {})
}
Since you have a repository, you can do the same thing you would do to test the view model.
- Create interface for
CityRepository
interface CityRepositoryI {
val allCities: List<City>
suspend fun addCity(city: City)
suspend fun updateCity(city: City)
suspend fun deleteCity(city: City)
suspend fun getCityById(id: Int)
}
- Implement it for
CityRepository
:
@ViewModelScoped
class CityRepository @Inject constructor(appDatabase: AppDatabase) : CityRepositoryI {
private val dao by lazy { appDatabase.getCityDao() }
override val allCities by lazy { dao.getAllCities() }
override suspend fun addCity(city: City) = dao.insert(city)
override suspend fun updateCity(city: City) = dao.update(city)
override suspend fun deleteCity(city: City) = dao.delete(city)
override suspend fun getCityById(id: Int) = dao.getCityById(id)
}
- Create
FakeCityRepository
for testing purposes:
class FakeCityRepository : CityRepositoryI {
// predefined cities for testing
val cities = listOf(
City(1)
).toMutableStateList()
override val allCities by lazy { cities }
override suspend fun addCity(city: City) {
cities.add(city)
}
override suspend fun updateCity(city: City){
val index = cities.indexOfFirst { it.id == city.id }
cities[index] = city
}
override suspend fun deleteCity(city: City) {
cities.removeAll { it.id == city.id }
}
override suspend fun getCityById(id: Int) = cities.first { it.id == id }
}
So you can pass it into your view model: HomeViewModel(FakeCityRepository())
You can do the same with AppDatabase
instead of a repository, it all depends on your needs. Check out more about Hilt testing
p.s. I’m not sure if this will build, since I don’t have some of your classes, but you should have caught the idea.