I have an Angular component, MyComponent, which calls a method returning an Observable and subscribes to it, something like
export class MyComponent {
someProperty;
constructor(service: MyService) {}
someButtonClicked() {
this.service.doStuffAsync().subscribe(
resp => this.someProperty = resp;
);
}
}
@Injectable()
export MyService {
doStuffAsync() {
// returns an Observable which notifies asychronously, e.g. like HttoClient.get(url)
}
}
I want to test the method someButtonClicked()
and therefore I create a MyServiceMock class which I inject in the test
export class MyServiceMock {
doStuffAsync() {
return of({// some object}).pipe(observeOn(asyncScheduler));
}
}
For whatever reason I want doStuffAsync()
of MyServiceMock to be asynchronous so observeOn(asyncScheduler)
is used.
At this point though I do not know how to test someButtonClicked()
. I have tried different strategies, e.g. the following
beforeEach(async(() => {
TestBed.configureTestingModule({
providers: [
{ provide: MyService, useClass: MyServiceMock },
]
}).compileComponents();
}));
let fixture: ComponentFixture<MyComponent>;
let component: MyComponent;
beforeEach(() => {
fixture = TestBed.createComponent(MyComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('test someButtonClicked', async(() => {
component.someButtonClicked();
fixture.whenStable().then(() => {
expect(component.someProperty).toBeDefined();
});
}));
but this fails since doStuffAsync()
of MyServiceMock asynchronous.
So my question is which is the best strategy to test the side effects (i.e. someProperty
being set correctly) induced by a method which subscribes to an asynchronous Observable.