Hi I have some unit tests for my multi-modular Android Project and I want to run a CI pipeline with these tests but as the header says some tests that are using mockk to mocking operations are failing on CI server (using Bitrise for this with a Ubuntu 22.04 machine) but every time in any situation works on my local machine (MB M1 Pro). I did a lot of research but neither any LLM out there or any blog couldn't help.
Here is my test class in my :feature_home
(which does not have access to repositories that is also why im mocking usecases) module:
@OptIn(ExperimentalCoroutinesApi::class)
@ExtendWith(MainCoroutineExtension::class)
class DetailViewModelTest {
private lateinit var viewModel: DetailViewModel
private lateinit var getForecastUseCase: GetForecastUseCase
private lateinit var savedStateHandle: SavedStateHandle
@BeforeEach
fun setUp() {
getForecastUseCase = mockk(relaxed = true)
savedStateHandle = SavedStateHandle()
viewModel = DetailViewModel(getForecastUseCase, savedStateHandle)
}
@Test
fun `given viewModel when initialized then forecastState should be Loading`() = runTest {
assertThat(viewModel.forecastState.value).isEqualTo(ForecastState.Loading)
}
@Test
fun `given savedStateHandle with null values when fetching forecast then state should remain Loading`() =
runTest {
savedStateHandle[DetailViewModel.LATITUDE_ARG] = null
savedStateHandle[DetailViewModel.LONGITUDE_ARG] = null
every { getForecastUseCase.execute(any(), any()) } returns flowOf(dummyForecast)
viewModel.forecastState.test {
val firstItem = awaitItem()
assertThat(firstItem).isEqualTo(ForecastState.Loading)
expectNoEvents()
}
}
}
GetForecastUseCase
:
class GetForecastUseCase @Inject constructor(
private val repository: WeatherForecastRepository
) {
fun execute(
lat: String,
long: String
): Flow<Forecast> = repository.getLocationForecast(lat, long)
}
(on CI) Here, first test always succeeds but the second one (which contains mocking operations) always fails with exception :
java.lang.NullPointerException: Cannot invoke "com.sevban.data.repository.WeatherForecastRepository.getLocationForecast(String, String)" because "this.repository" is null ...
As you can see its complaining about this.repository being null but the thing is I'm not mocking any repository, I'm only mocking the GetForecastUseCase
class that uses a repository as a dependency for making requests to API.
What did I try ?
I ran repeated tests thousands of times to see whether they are flakky tests or not but they never failed in my local machine.
Also I cleaned my gradle & Android Studio cache a lot of times but they were still succeeding in local, failing online.
Are there any suggestions to try on or should this be related with an issue about Bitrise ? Thanks in advance.
Okay, it is solved by changing the Java version of all my modules from 18 to 17.