Как принудительно инициализировать контекст в классе приложения перед тестированием с помощью Mockito - PullRequest
0 голосов
/ 12 марта 2020

Это мой класс приложения

class MainApplication : MultiDexApplication() {

    init { INSTANCE = this }

    companion object {

        lateinit var INSTANCE: MainApplication
            private set

        val applicationContext: Context get() { return INSTANCE.applicationContext }
    }


    override fun onCreate() {
        super.onCreate()

    }

}

И в моем тесте я должен прочитать текущую локацию, идущую отсюда в моем CurrentCityViewModel:

class LocationLiveData(applicationContext: Context) : LiveData<LocationModel>() {

    private var fusedLocationClient = LocationServices.getFusedLocationProviderClient(applicationContext)
....

}

Это мой тестовый класс CurrentCityViewModelTest

@RunWith(KotlinTestRunner::class)
@OpenedPackages("com.hend.weatherforecastchallenge")
class CurrentCityViewModelTest {

    @get:Rule
    val mockitoRule: MockitoRule = MockitoJUnit.rule()

    @get:Rule
    val taskExecutorRule = InstantTaskExecutorRule()

    @get:Rule
    val rxSchedulerRule = RxSchedulerRule()

    //     Test rule for making the RxJava to run synchronously in unit test
    companion object {
        @ClassRule
        @JvmField
        val schedulers = RxImmediateSchedulerRule()
    }

    @Mock
    lateinit var networkApiService: NetworkApiServices

    @Mock
    lateinit var observer: Observer<CityForecast>

    @Mock
    lateinit var currentCityViewModel: CurrentCityViewModel


    @Before
    fun setUp() {
        currentCityViewModel = CurrentCityViewModel()

    }


    @Test
    fun `init set forecast object to null`() {

        val forecast =
            currentCityViewModel.getCityForecast(LocationModel(37.5597, 55.4997))
                .testObserver()

        Truth.assert_()
            .that(forecast.observedValues).isNull()
    }

    @Test
    fun `getCityForecast set correct loading states`() {

        val status = currentCityViewModel.uiState.testObserver()

        currentCityViewModel.getCityForecast(LocationModel(37.5597, 55.4997))

        Truth.assert_()
            .that(status.observedValues)
            .isEqualTo(listOf(Loading, HasData))
    }


    @Test
    fun `getCityForecast set correct location`() {

        val cityForecast =
            currentCityViewModel.getCityForecast(LocationModel(37.5597, 55.4997)).testObserver()

        Truth.assert_()
            .that(cityForecast.observedValues)
            .isEqualTo(LocationModel(37.5597, 55.4997))
    }

    @Test
    fun `should show CityForecast data`() {

        val locationModel = Mockito.mock(
            LocationModel(37.5597, 55.4997)::class.java
        )

        val cityForecast = Mockito.mock(
            CityForecast(
                listOf(
                    Forecast(
                        Temperature(273.1, 265.32, 273.1, 273.1, 1011, 38),
                        listOf(Weather(803, "Clouds", "broken clouds", "04d")),
                        Wind(6.49, 313),
                        "12-3-2020"
                    )
                ), City(1, "Dubai", Coordinates(37.5597, 55.4997), "AE", 10800)
            )::class.java
        )


        // make the getCityWeather api to return mock data
        `when`(networkApiService.getFiveDaysWeather(37.5597, 55.4997))
            .thenReturn(Single.just(cityForecast))

        // observe on the MutableLiveData with an observer
        currentCityViewModel._cityForecast.observeForever { observer }
        currentCityViewModel.getCityForecast(locationModel)

    }

}

Я получил странное исключение при тестировании класса

kotlin.UninitializedPropertyAccessException: lateinit property INSTANCE has not been initialized

    at com.hend.weatherforecastchallenge.MainApplication$Companion.getINSTANCE(MainApplication.kt:13)
    at com.hend.weatherforecastchallenge.MainApplication$Companion.getApplicationContext(MainApplication.kt:16)
    at com.hend.weatherforecastchallenge.ui.currentcity.CurrentCityViewModel.<init>(CurrentCityViewModel.kt:34)
    at com.hend.weatherforecastchallenge.ui.currentcity.CurrentCityViewModelTest.setUp(CurrentCityViewModelTest.kt:61)

Я пытался получить контекст перед запуском теста, но безрезультатно. Кто-нибудь поможет мне, пожалуйста?

...