RxJava2 delay an observable until another observable emits
This is for unit testing purposes, as I want to verify correct behavior for a function where two data sources may return in different orders. Currently in my unit test, I'm creating an Observable with dummy data and simply using the delay operator to add a delay of 10 milliseconds for the data source I want to return second. However, this seems a bit ugly and could become problematic as I have more and more tests.
Is there a way to have an Observable wait to emit until another Observable completes?
Edit: Here's an example of a unit test that I have
public void testNetworkReturningBeforeLocal() {
Item localItem = new Item("local");
Item remoteItem = new Item("remote");
when(mDatabaseMock.getItem(any())).thenReturn(Observable.just(localItem).delay(10, TimeUnit.MILLISECONDS);
when(mApiMock.getItem(any())).thenReturn(Observable.just(remoteItem));
TestObserver<Item> observer = new TestObserver<>();
mRepository.getItem("blah").subscribe(observer); // calls getItem from database and API
observer.awaitTerminalEvent();
observer.assertResult(remoteItem);
}
I'm using delay(10, TimeUnit.MILLISECONDS)
on the observable returned by the database to simulate the network response arriving first. What I'd like to do is delay the database observable until the network observable completes.
observable delay rx-java2
|
show 1 more comment
This is for unit testing purposes, as I want to verify correct behavior for a function where two data sources may return in different orders. Currently in my unit test, I'm creating an Observable with dummy data and simply using the delay operator to add a delay of 10 milliseconds for the data source I want to return second. However, this seems a bit ugly and could become problematic as I have more and more tests.
Is there a way to have an Observable wait to emit until another Observable completes?
Edit: Here's an example of a unit test that I have
public void testNetworkReturningBeforeLocal() {
Item localItem = new Item("local");
Item remoteItem = new Item("remote");
when(mDatabaseMock.getItem(any())).thenReturn(Observable.just(localItem).delay(10, TimeUnit.MILLISECONDS);
when(mApiMock.getItem(any())).thenReturn(Observable.just(remoteItem));
TestObserver<Item> observer = new TestObserver<>();
mRepository.getItem("blah").subscribe(observer); // calls getItem from database and API
observer.awaitTerminalEvent();
observer.assertResult(remoteItem);
}
I'm using delay(10, TimeUnit.MILLISECONDS)
on the observable returned by the database to simulate the network response arriving first. What I'd like to do is delay the database observable until the network observable completes.
observable delay rx-java2
1
I would suggest you use aTestScheduler
and your observables use this scheduler. You will have to post a minimal test showing what you currently have for a more definitive answer. However it would seem that you can make this easier as all this is just to invoke subsequent behaviour, maybe you are trying to test too much at once - can you not refactor to just test the behaviours independently?
– Mark Keen
Nov 23 '18 at 1:22
A couple of ways with operators:delaySubscription
,delay(selector)
,concatEager
to name a few.
– akarnokd
Nov 23 '18 at 11:13
@MarkKeen I've added an example test case above
– theasianpianist
Nov 23 '18 at 22:27
@akarnokd none of those seem to work. DelaySubscription delays the subscription but not the emission of items, which is what I need. I'm already usingdelay
and want to avoid specifying a specific time to wait.concatEager
returns one observable, but these are two observables returning test data from two separate sources.
– theasianpianist
Nov 23 '18 at 22:32
I'm a little confused, it is quite feasible to assume that a network call would always be slower than returning a local persisted value? I'm not sure how valid this test is - are you trying to prove rxjava works? That said, for a solution, as stated you'll require aTestScheduler
, and use that with the delay operator, then forward time by 10 seconds, then make your assertions, also I'd make usefromCallable
instead ofjust
in your mock return values - reactivex.io/RxJava/javadoc/io/reactivex/schedulers/… you may also find theamb
operator useful here.
– Mark Keen
Nov 24 '18 at 0:22
|
show 1 more comment
This is for unit testing purposes, as I want to verify correct behavior for a function where two data sources may return in different orders. Currently in my unit test, I'm creating an Observable with dummy data and simply using the delay operator to add a delay of 10 milliseconds for the data source I want to return second. However, this seems a bit ugly and could become problematic as I have more and more tests.
Is there a way to have an Observable wait to emit until another Observable completes?
Edit: Here's an example of a unit test that I have
public void testNetworkReturningBeforeLocal() {
Item localItem = new Item("local");
Item remoteItem = new Item("remote");
when(mDatabaseMock.getItem(any())).thenReturn(Observable.just(localItem).delay(10, TimeUnit.MILLISECONDS);
when(mApiMock.getItem(any())).thenReturn(Observable.just(remoteItem));
TestObserver<Item> observer = new TestObserver<>();
mRepository.getItem("blah").subscribe(observer); // calls getItem from database and API
observer.awaitTerminalEvent();
observer.assertResult(remoteItem);
}
I'm using delay(10, TimeUnit.MILLISECONDS)
on the observable returned by the database to simulate the network response arriving first. What I'd like to do is delay the database observable until the network observable completes.
observable delay rx-java2
This is for unit testing purposes, as I want to verify correct behavior for a function where two data sources may return in different orders. Currently in my unit test, I'm creating an Observable with dummy data and simply using the delay operator to add a delay of 10 milliseconds for the data source I want to return second. However, this seems a bit ugly and could become problematic as I have more and more tests.
Is there a way to have an Observable wait to emit until another Observable completes?
Edit: Here's an example of a unit test that I have
public void testNetworkReturningBeforeLocal() {
Item localItem = new Item("local");
Item remoteItem = new Item("remote");
when(mDatabaseMock.getItem(any())).thenReturn(Observable.just(localItem).delay(10, TimeUnit.MILLISECONDS);
when(mApiMock.getItem(any())).thenReturn(Observable.just(remoteItem));
TestObserver<Item> observer = new TestObserver<>();
mRepository.getItem("blah").subscribe(observer); // calls getItem from database and API
observer.awaitTerminalEvent();
observer.assertResult(remoteItem);
}
I'm using delay(10, TimeUnit.MILLISECONDS)
on the observable returned by the database to simulate the network response arriving first. What I'd like to do is delay the database observable until the network observable completes.
observable delay rx-java2
observable delay rx-java2
edited Nov 23 '18 at 22:24
theasianpianist
asked Nov 22 '18 at 20:54
theasianpianisttheasianpianist
8819
8819
1
I would suggest you use aTestScheduler
and your observables use this scheduler. You will have to post a minimal test showing what you currently have for a more definitive answer. However it would seem that you can make this easier as all this is just to invoke subsequent behaviour, maybe you are trying to test too much at once - can you not refactor to just test the behaviours independently?
– Mark Keen
Nov 23 '18 at 1:22
A couple of ways with operators:delaySubscription
,delay(selector)
,concatEager
to name a few.
– akarnokd
Nov 23 '18 at 11:13
@MarkKeen I've added an example test case above
– theasianpianist
Nov 23 '18 at 22:27
@akarnokd none of those seem to work. DelaySubscription delays the subscription but not the emission of items, which is what I need. I'm already usingdelay
and want to avoid specifying a specific time to wait.concatEager
returns one observable, but these are two observables returning test data from two separate sources.
– theasianpianist
Nov 23 '18 at 22:32
I'm a little confused, it is quite feasible to assume that a network call would always be slower than returning a local persisted value? I'm not sure how valid this test is - are you trying to prove rxjava works? That said, for a solution, as stated you'll require aTestScheduler
, and use that with the delay operator, then forward time by 10 seconds, then make your assertions, also I'd make usefromCallable
instead ofjust
in your mock return values - reactivex.io/RxJava/javadoc/io/reactivex/schedulers/… you may also find theamb
operator useful here.
– Mark Keen
Nov 24 '18 at 0:22
|
show 1 more comment
1
I would suggest you use aTestScheduler
and your observables use this scheduler. You will have to post a minimal test showing what you currently have for a more definitive answer. However it would seem that you can make this easier as all this is just to invoke subsequent behaviour, maybe you are trying to test too much at once - can you not refactor to just test the behaviours independently?
– Mark Keen
Nov 23 '18 at 1:22
A couple of ways with operators:delaySubscription
,delay(selector)
,concatEager
to name a few.
– akarnokd
Nov 23 '18 at 11:13
@MarkKeen I've added an example test case above
– theasianpianist
Nov 23 '18 at 22:27
@akarnokd none of those seem to work. DelaySubscription delays the subscription but not the emission of items, which is what I need. I'm already usingdelay
and want to avoid specifying a specific time to wait.concatEager
returns one observable, but these are two observables returning test data from two separate sources.
– theasianpianist
Nov 23 '18 at 22:32
I'm a little confused, it is quite feasible to assume that a network call would always be slower than returning a local persisted value? I'm not sure how valid this test is - are you trying to prove rxjava works? That said, for a solution, as stated you'll require aTestScheduler
, and use that with the delay operator, then forward time by 10 seconds, then make your assertions, also I'd make usefromCallable
instead ofjust
in your mock return values - reactivex.io/RxJava/javadoc/io/reactivex/schedulers/… you may also find theamb
operator useful here.
– Mark Keen
Nov 24 '18 at 0:22
1
1
I would suggest you use a
TestScheduler
and your observables use this scheduler. You will have to post a minimal test showing what you currently have for a more definitive answer. However it would seem that you can make this easier as all this is just to invoke subsequent behaviour, maybe you are trying to test too much at once - can you not refactor to just test the behaviours independently?– Mark Keen
Nov 23 '18 at 1:22
I would suggest you use a
TestScheduler
and your observables use this scheduler. You will have to post a minimal test showing what you currently have for a more definitive answer. However it would seem that you can make this easier as all this is just to invoke subsequent behaviour, maybe you are trying to test too much at once - can you not refactor to just test the behaviours independently?– Mark Keen
Nov 23 '18 at 1:22
A couple of ways with operators:
delaySubscription
, delay(selector)
, concatEager
to name a few.– akarnokd
Nov 23 '18 at 11:13
A couple of ways with operators:
delaySubscription
, delay(selector)
, concatEager
to name a few.– akarnokd
Nov 23 '18 at 11:13
@MarkKeen I've added an example test case above
– theasianpianist
Nov 23 '18 at 22:27
@MarkKeen I've added an example test case above
– theasianpianist
Nov 23 '18 at 22:27
@akarnokd none of those seem to work. DelaySubscription delays the subscription but not the emission of items, which is what I need. I'm already using
delay
and want to avoid specifying a specific time to wait. concatEager
returns one observable, but these are two observables returning test data from two separate sources.– theasianpianist
Nov 23 '18 at 22:32
@akarnokd none of those seem to work. DelaySubscription delays the subscription but not the emission of items, which is what I need. I'm already using
delay
and want to avoid specifying a specific time to wait. concatEager
returns one observable, but these are two observables returning test data from two separate sources.– theasianpianist
Nov 23 '18 at 22:32
I'm a little confused, it is quite feasible to assume that a network call would always be slower than returning a local persisted value? I'm not sure how valid this test is - are you trying to prove rxjava works? That said, for a solution, as stated you'll require a
TestScheduler
, and use that with the delay operator, then forward time by 10 seconds, then make your assertions, also I'd make use fromCallable
instead of just
in your mock return values - reactivex.io/RxJava/javadoc/io/reactivex/schedulers/… you may also find the amb
operator useful here.– Mark Keen
Nov 24 '18 at 0:22
I'm a little confused, it is quite feasible to assume that a network call would always be slower than returning a local persisted value? I'm not sure how valid this test is - are you trying to prove rxjava works? That said, for a solution, as stated you'll require a
TestScheduler
, and use that with the delay operator, then forward time by 10 seconds, then make your assertions, also I'd make use fromCallable
instead of just
in your mock return values - reactivex.io/RxJava/javadoc/io/reactivex/schedulers/… you may also find the amb
operator useful here.– Mark Keen
Nov 24 '18 at 0:22
|
show 1 more comment
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53437873%2frxjava2-delay-an-observable-until-another-observable-emits%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53437873%2frxjava2-delay-an-observable-until-another-observable-emits%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
I would suggest you use a
TestScheduler
and your observables use this scheduler. You will have to post a minimal test showing what you currently have for a more definitive answer. However it would seem that you can make this easier as all this is just to invoke subsequent behaviour, maybe you are trying to test too much at once - can you not refactor to just test the behaviours independently?– Mark Keen
Nov 23 '18 at 1:22
A couple of ways with operators:
delaySubscription
,delay(selector)
,concatEager
to name a few.– akarnokd
Nov 23 '18 at 11:13
@MarkKeen I've added an example test case above
– theasianpianist
Nov 23 '18 at 22:27
@akarnokd none of those seem to work. DelaySubscription delays the subscription but not the emission of items, which is what I need. I'm already using
delay
and want to avoid specifying a specific time to wait.concatEager
returns one observable, but these are two observables returning test data from two separate sources.– theasianpianist
Nov 23 '18 at 22:32
I'm a little confused, it is quite feasible to assume that a network call would always be slower than returning a local persisted value? I'm not sure how valid this test is - are you trying to prove rxjava works? That said, for a solution, as stated you'll require a
TestScheduler
, and use that with the delay operator, then forward time by 10 seconds, then make your assertions, also I'd make usefromCallable
instead ofjust
in your mock return values - reactivex.io/RxJava/javadoc/io/reactivex/schedulers/… you may also find theamb
operator useful here.– Mark Keen
Nov 24 '18 at 0:22