Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not using lifecycle aware observer for unit tests #235

Merged
merged 6 commits into from
May 3, 2019

Conversation

kojadin
Copy link
Contributor

@kojadin kojadin commented Apr 24, 2019

Using MvRxTestRule to force not using life cycle aware observable for unit tests.
Fixes #198

@kojadin kojadin changed the title Not using lifecycle aware observer for unit tests (airbnb#198) Not using lifecycle aware observer for unit tests Apr 24, 2019
if (deliveryMode is UniqueOnly) {
activeSubscriptions.remove(deliveryMode.subscriptionId)
private fun <T : Any> Observable<T>.resolveSubscription(
subscriber: (T) -> Unit,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small comment: I would keep the order of these params consistent with the above functions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sense.

@@ -33,6 +33,7 @@ abstract class BaseMvRxViewModel<S : MvRxState>(
private val stateStore: MvRxStateStore<S> = RealMvRxStateStore(initialState)
) : ViewModel() {
private val debugMode = if (MvRxTestOverrides.FORCE_DEBUG == null) debugMode else MvRxTestOverrides.FORCE_DEBUG
private val forceUserTestObserver = MvRxTestOverrides.FORCE_USE_TEST_OBSERVER
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like a spelling mistake user instead of use

Is it necessary to add a property instead of referencing FORCE_USE_TEST_OBSERVER directly?

Copy link
Contributor Author

@kojadin kojadin Apr 25, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, actually on second thought , maybe I should call this FORCE_DISABLE_LIFECYCLE_AWARE_OBSERVER .
About using directly flag I was just trying to fallow same code style as you guys have for debugMode . I see that is a bit different in this case because of conditional. I don't have strong opinion on this, whatever you guys want.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kojadin you can use it directly inline and the new name sounds good 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Done

Copy link
Collaborator

@gpeal gpeal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems pretty reasonable to me. Can you include some tests to both test and demonstrate the usage of this?

@BenSchwab @elihart What do you think?

@@ -33,6 +33,7 @@ abstract class BaseMvRxViewModel<S : MvRxState>(
private val stateStore: MvRxStateStore<S> = RealMvRxStateStore(initialState)
) : ViewModel() {
private val debugMode = if (MvRxTestOverrides.FORCE_DEBUG == null) debugMode else MvRxTestOverrides.FORCE_DEBUG
private val forceUserTestObserver = MvRxTestOverrides.FORCE_USE_TEST_OBSERVER
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: forceUseTestObserver

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I was thinking to rename to forceDisableLifecycleAwareObserver and flag to FORCE_DISABLE_LIFECYCLE_AWARE_OBSERVER . WYT?

@@ -32,6 +32,7 @@ class MvRxTestRule(
RxAndroidPlugins.setMainThreadSchedulerHandler { Schedulers.trampoline() }
if (setRxImmediateSchedulers) setRxImmediateSchedulers()
MvRxTestOverridesProxy.forceMvRxDebug(debugMode.value)
MvRxTestOverridesProxy.forceUseTestObserver(true)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you intentionally make this not configurable? You can include it in the TestRule constructor as an optional and default-true param.

Copy link
Contributor Author

@kojadin kojadin Apr 25, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking to make it configurable, similar as for debugMode, but I could think on case when you will need lifecycle aware observer for unit tests. You can't use MvRxTestRule for automation tests because everything would happen in main thread. Maybe robolectric ? WYT ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually on second look Rx immediate schedulers are also configurable, so I make this also configurable.

@kojadin
Copy link
Contributor Author

kojadin commented Apr 25, 2019

Tests added.


init {
viewModel.subscribe {
subscribeCallCount++
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this not have been called before without your TestRule? Subscribe from inside of a viewModel isn't lifecycle aware because the ViewModel itself only has one lifecycle: onCleared. I expected this to be used to tests subscribing from the test itself.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is actually a fragment, I think the fact that it is in init is confusing, but I understand that's probably easier than driving lifecycle in the tests.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, this was the exact problem. This subscribe is an extension function available inside MvRxView. Without the TestRule, this callback was never called in unit tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly, this is a view and it would not be called before. There is a test MvRxTestRuleTestLifecycleAwareObserverEnabled where you can see that this wouldn't be called. The reason I used init is because I was trying to be consistent and use same approach that you guys have in TestRuleViewModel

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. Thanks for the explanation

Copy link
Contributor

@BenSchwab BenSchwab left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems reasonable to me

* This should only be set by the MvRxTestRule from the mvrx-testing artifact.
*
* This can be used to force MvRxViewModels to disable lifecycle aware observer for unit testing.
* This is Java so it can be packgage private.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo packgage

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed 👍

@gpeal gpeal merged commit 10febde into airbnb:master May 3, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

MvRxLifecycleAwareObserver breaks unit testability
5 participants