Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 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);
like image 304
Priyas Paulzagade Avatar asked Feb 21 '26 10:02

Priyas Paulzagade


1 Answers

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.

like image 51
Vasco Avatar answered Feb 23 '26 03:02

Vasco



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!