London804
London804

Reputation: 1126

How do you test observables in the ngOnInit lifecycle?

I've seen tons of articles on testing observables, including writing marble tests and somehow I still can't find a straight answer on how to test a simple observable in my component in my ngOnInit cycle.

ngOnInit(): void {
    this.selectedMembers$.subscribe((members) => {
        if (!!members) {
            this.store.dispatch(actions.getPCPs());
        }
    });

    this.membersForm.valueChanges.subscribe((id) => {
        if (!!id.member_id) {
            if (id.member_id === 'null') {
                this.store.dispatch(actions.getMembers());

                return;
            }
            this.store.dispatch(
                actions.getSelectedMember({ member_id: id.member_id }),
            );
        }
    });

    this.config$.subscribe((config) => {
        if (!!config) {
            config.mobile_filters.controls.forEach((control) => {
                this.formControlService.addControlToFormGroup(
                    this.mobileFiltersForm,
                    control,
                );
            });
        }
    });
}

In there a straight forward way to spyOn this component and check that these observables are emitting something?

 it('should test observables in ngOnInit', fakeAsync(() => {
    spyOn(component.selectedMembers$, 'subscribe')
    let myData;
    component.selectedMembers$.subscribe((data) => {
        myData = data;
        console.log('data',data);
        expect(myData).toEqual(data);
    })
}));

Upvotes: 4

Views: 5176

Answers (2)

gokumc
gokumc

Reputation: 188

What do you want to test exactly?

If you just want your subscribe callback to be called before your test finishes, you could use the tick() method in your test (https://angular.io/api/core/testing/tick):

it('should dispatch if members are provided / selected', fakeAsync(() => {
  // arrange
  const dispatchSpy = spyOn(component.store, 'dispatch');
  const membersToEmit = ['member-1', 'member-2'];
  component.selectedMembers$ = of(membersToEmit) // of from 'rxjs';

  // act
  component.ngOnInit();
  // alternatively you could call:
  // fixture.detectChanges();

  tick();  // causes your Observable to emit, so that the subscribe callback gets called 

  // assert
  expect(dispatchSpy).toHaveBeenCalled();
}));

Upvotes: 3

Klaudijus Valintėlis
Klaudijus Valintėlis

Reputation: 50

For example this part:

this.selectedMembers$.subscribe((members) => {
    if (!!members) {
        this.store.dispatch(actions.getPCPs());
    }
});

In your test:

const spy = spyOn(store, 'dispatch');
component.selectedMembers$.next('abc');
expect(spy).toHaveBeenCalledWith('abc');

Are you asking something like this ?

Upvotes: 0

Related Questions