airbnb / mavericks

Mavericks: Android on Autopilot
https://airbnb.io/mavericks/
Apache License 2.0
5.83k stars 500 forks source link

MvRxLifecycleAwareObserver breaks unit testability #198

Closed tasomaniac closed 5 years ago

tasomaniac commented 5 years ago

Currently all kind of subscribe and asyncSubscribe methods strongly depend on MvRxLifecycleAwareObserver which then depends on Android APIs.

Example call:

viewModel.asyncSubscribe(LoginState::token, onSuccess = {
    navController.navigate(R.id.open_search)
 })

It is almost impossible to unit test the implementation of functions given into asyncSubscribe and its siblings. Basically in unit tests, the fragment lifecycle will never be in resumed state and that's why MvRxLifecycleAwareObserver never calls the subsriber function.

romtsn commented 5 years ago

Agree here, looks like this needs to be exposed, or at least be VisibleForTesting for that.

tasomaniac commented 5 years ago

@rom4ek Technically the link you mentioned make sense. I can even use that function right now since it is only protected by lint and is public.

But since I'm testing the view layer, my code uses the one defined in MvRxView and that automatically retrieves the lifecycleOwner from the given Fragment.

romtsn commented 5 years ago

@tasomaniac Yeah, that's what I meant - it should be exposed via extension in MvRxView I guess.

tasomaniac commented 5 years ago

Another idea to solve this is to introduce this functionality into already existing TestRule: https://github.com/airbnb/MvRx/blob/master/testing/src/main/kotlin/com/airbnb/mvrx/test/MvRxTestRule.kt

This test rule would hook up into internals of MvRx and replace MvRxLifecycleAwareObserver with a regular one which will always subscribe in unit tests.