Angular & Jest Testing - Can't get image src from an anchor using [routerLink]?

193 views Asked by At

I am trying to test a component and there is an <img> tag but it is a child of an element that has an *ngIf. Even when I ensure that the if condition is always true, I still cannot grab the image source string. Angular does provide an attribute ng-reflect-ng-src however the string is truncated after 30 characters.

I have tried using waitForAsync, tick, fixture.whenStable, fakeAsync but nothing seems to be working and the source value is always an empty string, but never the actual link that it should be.

Here's some example code for the component HTML:

<div *ngIf="this.hero" class="hero_container">
  <img
    [ngSrc]="this.hero.hero_image"
    alt="hero"
    class="hero--broadband"
    fill
    priority
  />
</div>

Trying to get the element:

const image: HTMLImageElement = fixture.debugElement.query(By.css('.hero--broadband')).nativeElement;

Using Angular 15, what would be the correct way to wait for the image.src value to be set before trying to test against it?

Thanks!

1

There are 1 answers

2
Micah On

Here's something you can try:

  1. Import the waitForAsync and fakeAsync utilities from @angular/core/testing at the top of your test file:
import { waitForAsync, fakeAsync } from '@angular/core/testing';
  1. Modify your test to use the waitForAsync and fakeAsync utilities. Replace the existing test code with the following:
it('should have the correct image source', waitForAsync(() => {
  fixture.detectChanges(); 
// ^  Trigger change detetion to ensure the component renders

  const image: HTMLImageElement = fixture.debugElement.query(By.css('.hero--broadband')).nativeElement;

  const onLoad = () => {
    expect(image.src).toContain('expected-image-src'); 
    // ^ Replace 'expected-image-src' with the actual expected value

    fixture.destroy(); // Clean up the test environment
  };

  
  image.addEventListener('load', onLoad);
// wait for img to load ^

  // Manually trigger the load event in case the image is already cached
  if (image.complete) {
    onLoad();
  }

  // advance the clock --> asynchronous tasks triggers
  tick();

  // Check tht all asynchronous tasks are completed
  fixture.whenStable().then(() => {
    
    image.removeEventListener('load', onLoad);
    // ^ remove the load event listener to prevent memory leaks

  });
}));