1

In my unit test I want to call openDialog, openPdf, getPath with these three eventemitter that are in the ngOnDestroy 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);
}


ngOnDestroy(): 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.openDialog = emitter;
component.openPdf = emitter;
component.getPath = emitter;
emitter.emit(true);

1 Answers1

0

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.

Another anomaly in your code is your ngOnDestroy(). You call unsubscribe() to your EventEmitter, which you shouldn't do. Because EventEmitters should only be used to emit events from components, and hence they should not be subscribed to, there is no need to unsubscribe.
If you need to subscribe to it, you should rather use a Subject and not an EventEmitter with @Output.

Vasco
  • 418
  • 1
  • 8
  • 12
  • 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? – Priyas Paulzagade Jan 18 '23 at 11:19
  • I updated code snippet. – Priyas Paulzagade Jan 18 '23 at 11:32
  • 1
    Oh yeah. You have to use the `unsubscribe()` method on a Subscription and not on EventEmitter. So you can remove the content of your `ngOnDestroy()`, because you [should not and dont't have to subscribe/unsubscribe EventEmitter](https://stackoverflow.com/a/36076701/9740071). – Vasco Jan 18 '23 at 15:11
  • can you please tell me ,how can I dispatch Event for Eventemitter? – Priyas Paulzagade Jan 23 '23 at 17:10
  • For @Output and EventEmitter have a look at: [Angular - Sharing data between child and parent directives and components](https://angular.io/guide/inputs-outputs) – Vasco Jan 25 '23 at 16:04