How to spyon an observable property

Viewed 9173

I would like to unit test an Angular 10 component. In the component's ngOnInit method, this code appears:

this.subscriptions.push(
   this.myService.getDataSubject.subscribe((results) => {
      this.data = results;
   }
);

Also, in the unit test

beforeEach(async(() => {
    TestBed.configureTestingModule({
        providers: [MyService]
    }).compileComponents();
})

My unit test includes

beforeEach(() => {
    spyOnProperty(myService, 'getDataSubject', 'get').and.returnValue(of(mockData));
}

In the service itself

private dataSubject: BehaviorSubject<any> = new BehaviorSubject({});
getDataSubject = this.dataSubject.asObservable();

The unit test fails. I've tried multiple variations but cannot get the mockData value to be returned. When writing a unit test for a component that subscribes to a property tied to a BehaviorSubject, what am I supposed to do?

2 Answers

change

beforeEach(() => { spyOnProperty(myService, 'getDataSubject', 'get').and.returnValue(of(mockData)); }

to

beforeEach(() => {
    spyOn(myService, 'getDataSubject').and.callFake(()=>of(MockData));
}

Spy on the function and not on the property

@PMO1948: your suggestion sent me in the right direction. Here's what I had to do: Instead of

spyOn(myService, 'getDataSubject', 'get').and.returnValue(of(mockData));

I called the source function that populates the private BehaviorSubject:

myService.requestData().subscribe();

Then I spied on that function:

spyOn(myService, 'requestData').and.returnValue(of(mockData));

So that in my ngOnInit, when the service property is subscribed to the mockData is then returned. At least, that's what I think is happening, and my tests are passing.

Related