s-f
s-f

Reputation: 2141

How to test image events in Angular

Let's say we have a simple component that takes some actions on image event

<img src="{{imageUrl}}" (error)="onImageError($event)" (load)="onImageLoad()" width="{{imageWidth}}">

Now I want to test that this event handlers were triggered.

I tried the most simple approach

const spyError = spyOn(component, 'onImageError').and.callThrough();

fixture.detectChanges();

expect(spyError).toHaveBeenCalled();

It didn't work because the event loop is out of the execution stack of JavaSctipy. I tried to resolve it with asyn or fakeAsync but it didn't help.

The only worked solution is to use setTimeout inside the tests, which I don't really like.

So, my questions are

  1. Shall we test it at all? It looks like part of Angular/browser functionality. I can call component.onImageError() directly in a test.

  2. What is the clean way to test that event handler was called?

Upvotes: 2

Views: 2697

Answers (2)

Ian Hale
Ian Hale

Reputation: 31

The solution here worked for me Testing @HostListening('error') on Angular 7 directive

Selecting the image as a native element and using dispatchEvent to create the error was the ticket.

In my particular case the component included an *ngIf so I had to detect changes before I could select the native element.

html:

<ng-container>
  <ion-avatar *ngIf="src; else initials">
    <img [src]="src" (error)="onError($event)" [attr.data-src]="src" [alt]="firstName">
  </ion-avatar>

  <ng-template #initials>
    <app-initials [firstName]="firstName" [lastName]="lastName"></app-initials>
  </ng-template>
</ng-container>

Unit Test:

  it('should update the img element src attribute for an invalid image', () => {
    component.firstName = 'Aiza';
    component.lastName = 'Raymond';
    component.src = 'invalid';

    fixture.detectChanges();

    const img = fixture.debugElement.nativeElement.querySelector('img');
    const spyError = spyOn(component, 'onError' ).and.callThrough();
    img.dispatchEvent(new Event('error'));

    fixture.detectChanges();

    expect(spyError).toHaveBeenCalled();
  });

Upvotes: 2

Fateh Mohamed
Fateh Mohamed

Reputation: 21367

try this using whenStable

 it('should trigger', async(() => {
  const spyError = spyOn(component, 'onImageError').and.callThrough();
  // add something here that can trigger error, like setting src property with an invalid path
  fixture.detectChanges();
  fixture.whenStable().then(() => {
    expect(spyError).toHaveBeenCalled();
  });
}));

Upvotes: 0

Related Questions