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);
