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

LiveData seems to not notify observers #3234

Open
vpratfr opened this issue Jul 12, 2017 · 6 comments

Comments

Projects
None yet
8 participants
@vpratfr
Copy link

commented Jul 12, 2017

I am running latest Robolectric within Android Studio 2.3.3

I have described the issue more in details at Stackoverflow. But after some debugging, I feel that the problem may be something from Robolectric.

https://stackoverflow.com/questions/45054972/robolectric-test-and-livedata

Here is the test function:

@Test
fun should_redirect_to_login_when_time_is_up_after_onStart() {
    val timeUp = MutableLiveData<Boolean>()

    kodein.addConfig {
        bind<SplashViewModel>(overrides = true) with factory {
            _: BaseActivity -> mock<SplashViewModel> { on { isTimeUp() } doReturn timeUp }
        }
    }

    val activity = Robolectric.buildActivity(SplashActivity::class.java).create().start().resume().get()
    timeUp.value = true

    val startedIntent = shadowOf(activity).nextStartedActivity
    assertThat(startedIntent).isNotNull
    assertThat(startedIntent).hasComponent(application.packageName, LoginActivity::class.java)
}

I have another test which demonstrates that the mock is properly used by the activity ( I log the livedata instance used in onCreate and it is the same as the one from the test)

@brettchabot

This comment has been minimized.

Copy link
Contributor

commented Jul 17, 2017

Sorry its a little difficult for us to tell what is going wrong. Is it possible for you to provide a simpler repro case, ideally using Java?

@dmykhailenko

This comment has been minimized.

Copy link

commented Jul 28, 2017

Got the same problem. Using latest Robolectric version 3.4.
Here is a simple example that fails test where it shouldn't:
`
public class TestLifecycleActivity extends LifecycleActivity {

private TestViewModel viewModel;
private Observer<String> dataChangeObserver;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    viewModel = ViewModelProviders.of(this).get(TestViewModel.class);
    viewModel.getData().observe(this, dataChangeObserver);
}

public TestViewModel getViewModel() {
    return viewModel;
}

public void setDataChangeObserver(Observer<String> observer) {
    dataChangeObserver = observer;
}

}
`

`
public class TestViewModel extends AndroidViewModel {

private MutableLiveData<String> data = new MutableLiveData<>();

public TestViewModel(Application application) {
    super(application);
}

public MutableLiveData<String> getData() {
    return data;
}

}
`

`
@RunWith(RobolectricTestRunner.class)
public class LifeCycleActivityTest {

@Rule
public InstantTaskExecutorRule executorTestRule = new InstantTaskExecutorRule();

@Mock
Observer<String> dataChangeObserver;

@Test
public void testDataChanges() {
    MockitoAnnotations.initMocks(this);
    ActivityController<TestLifecycleActivity> activityController = Robolectric.buildActivity(TestLifecycleActivity.class);
    activityController.get().setDataChangeObserver(dataChangeObserver);
    activityController.setup();

    activityController.get().getViewModel().getData().setValue("test");

    verify(dataChangeObserver).onChanged("test");
}

}
`

@garmstro

This comment has been minimized.

Copy link

commented Aug 1, 2017

It looks like Robolectric does not trigger the Android Lifecycle methods when it creates the activity. I was able to workaround this by calling the "handleLifecycleEvent" method on the activity.

activityController.get().getLifecycle().handleLifecycleEvent(Lifecycle.Event.ON_START)
@ashmosaheb

This comment has been minimized.

Copy link

commented Feb 18, 2018

@garmstro @vpratfr I am having the same issue. but cannot solve this with the work-around as .handleLifecycleEvent() is not exposed by the latest Lifecycle object from AppCompatActivity

@Manikkumar1988

This comment has been minimized.

Copy link

commented Jan 17, 2019

Same with v4's FragmentActivity, there is no method handleLifecycleEvent or getLifecycle() and onChanged is not fired!

@slott

This comment has been minimized.

Copy link

commented Jun 15, 2019

Right after needing to wait for a liveData callback I am now calling shadowOf(getMainLooper()).runOneTask(); and that does the trick. This forces the pending background task to be executed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.