Búsqueda de sitios web

angular - Cómo escribir un caso de prueba unitaria en Jasmine para que la función se llame en el onerror de la etiqueta img


A continuación se muestra el código que estoy usando, pero este caso de prueba está fallando

//test case 
    it('should display default image if the image link in people finder result doesnot exist', fakeAsync(() => {
      debugger
      component.resultsItem = MOCK_RESULTSET.results[9];
      component.resultsItem.imageUrl = "https://domain/gxc3/files/Employee_Images/Test.jpg";
      fixture.detectChanges();
      tick(3000);
      el = fixture.debugElement.queryAll(By.css('.item-person-type'))[0].nativeElement;
      console.log(el);
      let src = el.getAttribute('src');
      expect(src).toBe("assets/img/user-icon.jpg");
    }));

//image tag

 <img class='item-person-type' title="{{resultsItem.text}}"
           [src]="resultsItem.imageUrl ? resultsItem.imageUrl : 'assets/img/user-icon.jpg'"
           (click)="onResultLinkClick(resultsItem)"
           (error)="getImageUrl()" />


//component function

getImageUrl() {
    try {
      var gxcUrl: string = this.resultsItem.imageUrl;
      this.resultsItem.imageUrl = 'assets/img/user-icon.jpg';
      var extensions = this._appSettingsService.appSettings.probableGxcImageExtensions;
      var imageExists = false;
      var probableImageUrls = [];
      extensions.forEach(function (extension) {
        let probableImageUrl = gxcUrl.replace(".jpg", extension);
        probableImageUrls.push(probableImageUrl);
      })
      let observables = probableImageUrls.map(probableImageUrl => this.checkImage(probableImageUrl))
      let source = Observable.forkJoin(observables);
      source.subscribe(response => {
        for (var i = 0; i < response.length; ++i) {
          if (response[i]) {
            imageExists = true;
            this.resultsItem.imageUrl = probableImageUrls[i];
            break;
          }
        }
        if (!imageExists) {
          this.resultsItem.imageUrl = 'assets/img/user-icon.jpg';
        }
      });
    }
    catch (e) {
      this.resultsItem.imageUrl = 'assets/img/user-icon.jpg';
    }
  }

  checkImage(src): Observable<Boolean> {
    return Observable.create((observer: Observer<boolean>) => {
      let img = new Image();
      // img.crossOrigin = 'Anonymous';
      img.src = src;
      if (!img.complete) {
        img.onload = () => {
          observer.next(true);
          observer.complete();
        };
        img.onerror = (err) => {
          observer.next(false);
          observer.complete();
        };
      } else {
        observer.next(true);
        observer.complete();
      }
    });
  };


Los métodos getImageUrl se llaman cada vez que la imagen no se carga y reemplazan la extensión de la imagen actual (.jpg) y la buscan de nuevo con una extensión diferente como .png o .jpeg; si no se encuentra la imagen con ninguna de las extensiones, se muestra la imagen predeterminada.

Respuesta #1

La solución general para probar partes de objetos difíciles de acceder es trasladar su creación a fábricas, así que por ejemplo, si tienes:

class A {
  run() {
    const v = new B(x, y);
    v.doSomeStuff(z, t);
  }
}

puedes hacer algo así:

class A {
  constructor(private bFactory) {}

  run() {
    const v = this.bFactory(x, y);
    v.doSomeStuff(z, t);
  }
}

y luego en las pruebas puedes inyectar algo como esto:

const bMock = { doSomeStuff: jasmine.createSpy('doSomeStuff') }; 
const bFactoryMock = jasmine.createSpy('bFactoryMock').and.return(bMock);
const tested = new A(bFactoryMock);

tested.run():

expect(bFactoryMock).toHaveBeenCalledWith(something, something);
expect(bMock.doSomeStuff).toHaveBeenCalledWith(something, something);