Comments

edited

It would be splendid if there was documentation for how one would go about testing complex Observable operator chains.

This is coming from a Angular 2 perspective, where one would probably use dependency injection to inject a different Scheduler inside of the tests: i.e when doing Observable.timer(1000, AsyncScheduler), one would change the AsyncScheduler to a TestScheduler.

I've tried finding documentation (or pretty much any instructions from anyone) on how one would go about actually instrumenting these Schedulers to test Observable sequences, but it's very hard to actually figure out since the APIs have seemingly changed quite a bit going from version 4 to 5 (e.g. scheduleAbsolute which is used in most testing examples for Rxjs 4, is totally absent).

Neither the unit tests nor the Scheduler docs were very helpful either in this regard.

This comment has been minimized.

edited

Yes, some clear example of you can control the ticking of the TestScheduler would be nice. I've skimmed through the source code and spec-files but couldn't find any clear examples of how to achieve this.

This comment has been minimized.

Agreed. This has been a big blocker for my team in trying to get a production-ready, ground-up 5.0 application off the ground. At least adding something to the migration document, since it seems a lot has changed in the way TestScheduler works, would be very helpful.

But I'm still a pretty bad writer, so the text is pretty verbose I think. The snippets might be worth something to someone.

Basically I inject Rx.Observable.empty() when not testing the emitted events.
I use Subject to manually mock a stream I want to test.
I use fooStream.take(1).subscribe to end hot observable streams.
I call fooSubject.next({value: 'foo'}) and assert inside subscribe.
If I have a playback of last value (BehaviorSubject() / publishReplay(1)), then I call next before subscribe.
Else, I call next after the subscribe call.

This is entirely without any scheduling simply because we haven't needed any yet. It is just a starting point, but it got us far with very complicated compositions of streams and saved my ass many times.

We also have a set of (user-)triggered actions that we can expose temporarily on the DOM by doing window.myComponent = myComponent and then open the web console and write myComponent.behaviors.triggers.addTodo({title: 'foo', body: 'bar'}) to fake user interactions without any renderable content.

It also enables us to programmatically play user behaviors on different components and check that the app state is correct. And that could ofc be sent to a database log.

This comment has been minimized.

edited

Did this progress anywhere?
Also stuck with testing and can't find any resource about how to test my current services. Whenever I ask about it people direct me to the RxJS tests, but I don't control the source Observables unless I copy/paste my logic, but that's not actually testing.

This comment has been minimized.

+1 on all this. The marble diagrams are nice, but it's entirely unclear how you'd use them to test an observable containing multiple time-based operators (i.e. real world problems). Having previously worked with Rx.net, RxJava, and RxJs4, with easy testability being one of the greatest features of Rx, it's fairly frustrating that all the standard Rx testing conventions have been seemingly abandoned.

This comment has been minimized.

I am very keen also to find out when we will have good documentation and stable interfaces to set up testing for complex Observable.timer cases. Would be good to know at least whether there are clear plans to have this in place in the near future.

Then I wanted to test that observable chain logic. The best way I found was to split it into a new method (I didn't like this because now I have a method exposed (public) only for test purpose, but whatever):

Please let me know your impressions about this approach. This basically mimics the way they test the rxjs lib.
Oh, and I don't know if this would work for operations using interval for example (prob not), otherwise it seems to work.

From that example, I wanted to be able to test that the mainWallet is transforming cents to dollars: 1000 to 10 but upon Instantiation of the class, it's already consumed the previous Observable in the chain.

I found that I can use Observable.defer so that the properties are only consumed when you subscribe to an Observable property, meaning you can test individual pieces by replacing them before they're subscribed to:

This comment has been minimized.

Could a step 1 of documenting testing be a doc about where to get the methods for marble tests at least?
I'm not using wallaby and I'm trying to find the reference to expectObservable but I can't find it anywhere in Rx

This comment has been minimized.

Is there a way at all to write a test without external dependencies? I'm trying to keep it simple, as in functions with assertions (or tape runner). The only examples of a full working tests I found used either wallaby or karma and while I know these are not related, I can't seem to find out how to run a test without them.

This comment has been minimized.

@naugtur I don't get this part, since our test is only relying on test runner (mocha and some assertions) only. Wallaby.js is just another test runner configuration and we don't have karma even. if you're doing npm test in our repo, it just works with mocha only.

This comment has been minimized.

I'm happy to move elsewhere not to derail this thread.
What I mean is I'm trying to get a TestScheduler, set it up and get my code to run. Maybe assert something. I can't find what I need to import/require to get all the necessary parts. scheduler.createHotObservable was easy to find, but I don't know how to get the scheduler to start and how to assert.

This comment has been minimized.

@martinsik I saw that stackoverflow thread and it's been a source of great confusion to me, as scheduler doesn't have the methods used in the top answer. (not even .flush)
Is the answer outdated, or should I use the package in a different way? I've built the code with webpack1 and commonjs syntax, so it couldn't have removed the methods.

This comment has been minimized.

I can recommend you to look at this project while there's no official solution.https://github.com/cartant/rxjs-marbles
Supports: Jasmine, Mocha, Jest, AVA and Tape. Syntax differs slightly but most marble-test features are there, although not the ones from RxJS4.
See Stackblitz for some examples.