question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. ItĀ collects links to all the places you might be looking at while hunting down a tough bug.

And, if youā€™re still stuck at the end, weā€™re happy to hop on a call to see how we can help out.

DISCUSSION 2: ObserverSpy API - passing `OnComplete` callback in the constructor?

See original GitHub issue

CONTEXT:

Following #12 (by the amazing @ThomasBurleson) we had a discussion and realized this PR could be separated into several PRs, and before that we need to discuss them.

This one is about: the possible changes to the ObserverSpy API to make it more ā€œgettersā€ focused.

The suggested API changes to ObserverSpy -


export type CompletionCallback = (spy: ObserverSpy<any>) => void;
const NOOP = () => {};

export class ObserverSpy<T> implements Observer<T> {

	constructor(private onCompleteCallback: CompletionCallback = NOOP) {}

...

	complete(): void {
    	this._state.called.complete = true;
	    this.onCompleteCallback(this);
	  }

...

The upsides (IMO) -

  • You define it one time and cannot change it afterwards (might reduce confusion?)

The downsides (IMO) -

  • It forces you to write your expectations before you trigger your action, meaning your test could end up looking like this:
it('should do something', ()=>{
	// SETUP
	const observerSpy = new ObserverSpy((spy)=>{
		// OUTCOME
		expect(spy.getValuesLength()).toBe(2);
	})

	// ACTION
	observableUnderTest.subscribe(observerSpy);

	// I personally don't like this style, I prefer to follow the "setup, action, outcome" structure in that order
	// because it keeps the tests more readable and predictable IMO.
});

  • It introduces 2 ways to do 1 thing, which is something Iā€™d like to avoid to keep the library as simple as possible so people wonā€™t have to guess ā€œwhatā€™s the best wayā€. Plus, if you keep the onComplete method, you then have another discussion to have - ā€œwhat happens when you define both callbacks? do they co-exist or not?ā€

Iā€™d love to hear your thoughts / corrections @ThomasBurleson @katharinakoal @edbzn @burkybang @yjaaidi (and whoever is interested), before we decide whether to break it into its own PR.

SOā€¦ WHAT DO YOU THINK?

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:8 (5 by maintainers)

github_iconTop GitHub Comments

4reactions
shairezcommented, Jul 6, 2020

Thanks @katharinakoal @NetanelBasal @yjaaidi for your feedback!

Younes - yeah, I agree with returning a promise Thatā€™s what was solved by @edbzn 's PR #3

The original observerSpy.onComplete() callback was added because I just didnā€™t think about async-await. And thatā€™s why I love open-source so much šŸ˜„

One use case I can think of is maybe older code that doesnā€™t support async-await or promises, but I donā€™t think itā€™s that common, so we might just remove it in the futureā€¦

2reactions
yjaaidicommented, Jul 6, 2020

Solution: I wouldnā€™t implement this feature. šŸ˜

Alternative: I would replace by it by .whenComplete(): Promise and only document usage for await observer.whenComplete().

Reason: I think that tests should never use callbacks because:

  • they makes tests harder to read
  • most users might forget to call done()
  • allowing callbacks encourages waterfall
  • it kind of breaks one of the purposes of ObserverSpy which is to avoid assertions in the subscribe

If we keep it, I would expect it to be an Observable so I can use it this way observer.onComplete.subscribe(completeObserverSpy) šŸ˜œ

I might miss some edge case where a callback is easier to readā€¦ but I canā€™t figure it out.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Passing a callback function to another class - Stack Overflow
You can pass it as Action<string> - which means it is a method with a single parameter of type string that doesn't return...
Read more >
Understanding CallBacks using Python ā€” Part 2 - Medium
Now our callback class has 2 new methods before_call and after_call, which are expected in slow_calculation function if callback is passed. WeĀ ...
Read more >
Understanding Callback Methods with Examples - OneSpan
Let's call the interface ActionListenerCallback , with the abstract methods onActionSuccess and onActionFailure , which will be passed withĀ ...
Read more >
RxJS Observable in depth - Jstobigdata
RxJS has built-in query implementation over observable sequences such as events, callbacks, Promises, HTML5 Geolocation APIs, and much muchĀ ...
Read more >
Flutter - Working with Callback Functions - GeeksforGeeks
Method 2: Passing the callback function. In this approach, the callback is directly passed to the event. As shown in the below example,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found