Cannot Read Property 'subscribe' of Angular Test Mock
Use inject to inject the service and mock it not stub
it('should create', inject([MyService], (myService: MyService) => {
spyOn(myService, 'getObservable').and.returnValue({subscribe: () => {}});
expect(component).toBeTruthy();
}));
Here is full version:
component:
@Component({
selector: 'my-cmp',
template: 'my cmp {{x}}'
})
export class MyComponent {
x;
constructor(private myService: MyService) {
this.myService.getObservable()
.subscribe(x => {
console.log(x);
this.x = x;
});
}
}
test:
describe('my component test', () => {
let fixture: ComponentFixture<MyComponent>, comp: MyComponent, debugElement: DebugElement, element: HTMLElement;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [MyComponent],
providers: [MyService]
});
}));
beforeEach(() => {
fixture = TestBed.createComponent(MyComponent);
comp = fixture.componentInstance;
debugElement = fixture.debugElement;
element = debugElement.nativeElement;
});
it('should create', inject([MyService], (myService: MyService) => {
expect(comp).toBeTruthy();
}));
it('should set value', async(inject([MyService], (myService: MyService) => {
spyOn(myService, 'getObservable').and.returnValue(Observable.of(1));
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(comp.x).toEqual(1);
});
})));
});
Related videos on Youtube
Dan Forbes
Former wine industry professional and graduate of the University of Texas at Austin with a Bachelor of Science degree in Computer Science.
Updated on June 04, 2022Comments
-
Dan Forbes almost 2 years
I'm trying to unit test an Angular component that has an injected service. In the component's constructor, a method on the injected service is called that returns an Observable. I'm trying to mock the service in my component's unit test, but I keep running into this error:
TypeError: Cannot read property 'subscribe' of undefined
.I've tried to mock the service in the following ways:
const serviceStub = { getObservable: () => { return {subscribe: () => {}}; }, }; beforeEach(async(() => { TestBed.configureTestingModule({ providers: [ {provide: MyService, useValue: serviceStub} ] }) it('should create', () => { spyOn(serviceStub, 'getObservable').and.returnValue({subscribe: () => {}}); expect(component).toBeTruthy(); });
It feels like I'm missing something obvious. Can someone please point it out?
UPDATE
I get this error even when I inject the actual service in my test bed providers.
The component's constructor looks something like this:
private _subscription: Subscription; constructor(private _service: MyService) { this._subscription = _service.getObservable().subscribe(console.log); }
-
Dan Forbes almost 7 yearsThank you for your reply, Julia! I look forward to trying this out as soon as I get home!
-
Julia Passynkova almost 7 yearswelcome. let me know. i have a lot of test similar to that
-
Julia Passynkova almost 7 yearsi updated the answer. it works for me. please try again.
-
Dan Forbes almost 7 yearsI appreciate your follow-up, but unfortunately, it's still failing with the same error. I looked at the output a little harder, and it appears that the error is coming from the call to
TestBed.createComponent
, which makes the fact that your suggestions aren't helping make a little more sense, at least...