1

I have been watching videos and reading articles, but so far they are all either over my head, or are too simplistic. (Looking for a good goldilocks-type practical explanation here.)

I have an angular service that has an observable property, like so, where the property I want to test is message$:

@Injectable()
export class MyMessageService {
    private messageSubj = new BehaviorSubject("");
    public message$ = this.messageSubj.pipe(filter(msg => !!msg));
    
    public someFunction(msg: string): void {
        this.messageSubj.next(msg);
    }
}

message$ should not emit at all, until the subject gets next'd in some way.

All the tests that I've found (at least, that make sense to me), are defining 3 observables: a source$, expected$, and result$, then comparing the last 2, thusly:

it("should be easier to test than this", () => {
    scheduler.run((helpers: RunHelpers) => {
        const source$ = helpers.cold("-a-b|", { a: "", b: "hello" });
        const expected$ = helpers.cold("---b|", { b: "hello" });
        
        const result$ = source$.pipe(filter(x => !!x));
        helpers.expectObservable(result$).toEqual(expected$);
    });
});

Now, if I want to test my service's message$ observable, how would I alter the above test? Would I replace source$ with const source$ = myService.message$? Is that correct?

If I do that, I can test that it DOESN'T emit (WOOHOO!). But how can I test it such that, at "a" the source does not emit, but either before or at "b", I call myService.someFunction("hello") so that at "b", the value is "hello"?

Thanks!

emery.noel
  • 1,073
  • 1
  • 9
  • 24

1 Answers1

0

I am not sure about the test example you found; I would test message$ to emit some desire value like this:

  it('should emit a value when calling someFunction function', () => {
    service.someFunction('Hello');

    // success
    service.message$.subscribe((message) => expect(message).toEqual('Hello'))
  })

  it('should not emit any value from messages$', () => {
    // success, although is missing expectations
    service.message$.subscribe((message) => expect(message).toBeUndefined())
  })

message$ should not emit at all, until the subject gets next'd in some way.

message$ should not emit at all if no one subscribes to the observable, even if I call someFunction nexting the value, if no one is subscribe to messages$, then it will not emit anything.

If I do that, I can test that it DOESN'T emit (WOOHOO!).

Correct, since no one is subscribing to $messages, there is no value emitted

Andres2142
  • 2,622
  • 2
  • 14
  • 19
  • Well, the message service is just an example, the real service emits a complex object. I don't want it to be able to emit undefined, I want it to ALWAYS have a value when it emits; otherwise I will be false-checking throughout the entire app, and that gets tiresome. I'd like to test in one go, testing that even if I subscribe, it won't emit until the value is next'd. Good point about the "it won't emit until next AND sub". – emery.noel Mar 04 '22 at 10:43