I've been trying to test a function that contains a subscribe of an EventEmitter, the unit test is calling the subscribe but It has been impossible to test the code inside the subscribe, I mean, the filter
and getDocuments()
are not being tested even though the subscribe is being called.
describe('trigger_data test', () => {
it('not filter in storage', async(() => {
component.filter = null;
spyOn(component, 'getDocuments');
spyOn(mockSharedService.trigger_data, 'subscribe').and.returnValue(of(true));
component.triggerData();
expect(mockSharedService.trigger_data.subscribe).toHaveBeenCalled();
expect(component.filter).toEqual(1); //Error: Expected null to equal 1.
expect(component.getDocuments).toHaveBeenCalled(); //Error: Expected spy getDocuments to have been called.
}));
});
This is the function
triggerData() {
this.sharedService.trigger_data.subscribe(() => {
if (sessionStorage.getItem('filter_pp') !== null) {
this.filter = Number(sessionStorage.getItem('filter_pp'));
} else {
this.filter = 1;
}
this.getDocuments();
});
}
When another component emits a boolean the subscribe trigger the code.
You are spying on the subscribe
method and having it return an Observable, which is not correct. (subscribe is a method on an Observable that returns a Subscription)
There are a few ways you can go about fixing this:
mockSharedService.trigger_data = of(true)
(Note: if trigger_data is an EventEmitter, TypeScript is not going to like this and you might need: mockSharedService.trigger_data = of(true) as any
) const emitter = new EventEmitter();
mockSharedService.trigger_data = emitter;
emitter.emit(true);
spyOn(mockSharedService, 'trigger_data').and.returnValue(of(true))
. However, doing so will also require you to change your triggerData
implementation to call trigger_data()
instead of just accessing it as a property.I've been trying to test a function that contains a subscribe of an EventEmitter
Additional, you probably want to use a Subject instead of an EventEmitter, EventEmitters are used by Angular for their Output bindings. When implementing ourselves, outside of Angular's Outputs we can make use of Subjects instead of EventEmitters (which actually extends Subjects, for the purpose of Angular's Outputs. See: https://github.com/angular/angular/blob/master/packages/core/src/event_emitter.ts#L64)