menu

Questions & Answers

Angular Unit - Testing how to subscribe event emitter

In my unit test I want to call openDialog, openPdf, getPath with these three eventemitter that are in the ngOnDestroyed method. How can I call them?

component.ts:

pdfPath: string = ''; // will be edited later

@Output() openDialog = new EventEmitter();
@Output() openPdf = new EventEmitter();
@Output() getPath: EventEmitter<string> = new EventEmitter();
 
getData() {
  // ...
  this.openDialog.emit(true);
}

showData() {
  // ...
  this.openPdf.emit();
}

fetchData() {
  // ...
  this.getPath.emit(this.pdfPath);
}


ngOnDestroyed(): void {
    this.openDialog.unsubscribe();
    this.openPdf.unsubscribe();
    this.getPath.unsubscribe();
}

I've tried calling them like this in the beforeEach and use spyOn(component.openDialog, 'subscribe'); , but this isn't working:

const emitter = new EventEmitter();
component.openErrorMessageDialog = emitter;
component.loadedPdf = emitter;
component.getPdfLocalPath = emitter;
emitter.emit(true);
Answers(1) :

I hope I have understood your problem correctly.

If you want to check if the emit function was called, then you can check this with a spy:

it('#getData should emit openDialog', () => {
  const emitSpy = spyOn(component.openDialog, 'emit');

  component.getData();

  expect(emitSpy).toHaveBeenCalled(); // checks if `openDialog.emit()` has been called
  expect(emitSpy).toHaveBeenCalledWith(true); // checks if `openDialog.emit()` has been called with `true`
});

For more information about spies, just search for "Jasmine Spies".

If you simply use the emit() function in a unit test then you can do that with the automatically generated component variable:

describe('BookShelfComponent', () => {
  let component: BookShelfComponent; // your component
  let fixture: ComponentFixture<BookShelfComponent>;

  // ...

  beforeEach(() => {
    fixture = TestBed.createComponent(BookShelfComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('#openDialog.emit should emit openDialog', () => {
    const emitSpy = spyOn(component.openDialog, 'emit');

    component.openDialog.emit(); // call `emit()`

    expect(emitSpy).toHaveBeenCalled(); // only for the demonstration that `emit()` was executed
  });
});

If that didn't answer your question, try again to describe your problem more clearly.

Comments:
2023-01-18 11:42:02
thank you for your answer, but issue are still there. when I run unit test case I am facing "Unhandled promise rejection: ObjectUnsubscribedError: object unsubscribed" error. if I commented code that is written in ngOnDestroyed method then I am not facing any error, to solve this error I think I need to subscribe eventemitter in spec file. so how can I solve this issue?
2023-01-18 11:42:02
I updated code snippet.