Tips on creating a Jasmine unit test scenario for a function that triggers onerror of an image tag

I am facing an issue with the code below as the test case is failing

//test case 
    it('should display default image if the image link in people finder result does not 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();
      }
    });
  };


The getImageUrl method is triggered when an image fails to load. It updates the source by replacing the current image's (.jpg) extension and retries loading it with other extensions like .png or .jpeg. If none of the extensions work, the default image is displayed.

Answer №1

To simplify testing of difficult-to-access object components, a common approach is to delegate their creation to factories. For instance:

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

This can be refactored as follows:

class A {
  constructor(private bFactory) {}

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

Subsequently, during tests, you can implement something like this:

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

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Error in Angular Services due to Circular Dependency

I am encountering the following error message: Provider parse errors: Cannot instantiate cyclic dependency! Within my code, I have a Component dedicated to making HTTP calls to my backend server: backend.component.ts import { Http } from '@angul ...

Learn the process of generating dynamic rows in HTML

Currently, I'm working on a website where I am incorporating the Flipkart API to display a list of products. However, the products are not appearing in the well-formatted view that I had designed. Specifically, I want only 4 products to show per row b ...

Using TypeScript: Union Types for Enum Key Values

Here's the code in the TS playground too, click here. Get the Enum key values as union types (for function parameter) I have managed to achieve this with the animals object by using key in to extract the key as the enum ANIMALS value. However, I am s ...

Updating the user interface in Angular when receiving data via socket.io is currently not feasible

Everything is functioning correctly in my sample application with the web client connecting to the socket.io server. The data being sent by the server over the websocket are being received properly by the client. However, there seems to be an issue when va ...

Troubleshooting Angular 2 RC5: detectChanges function not functioning as expected

Currently, I am working on developing a login form component that has the following interface: <login-form onlogin="submit()"></login-form> Here is the testing code for this component: it("Ensuring credentials are passed correctly out of t ...

Error when navigating to a dynamic parameter path using Angular Router

I'm trying to redirect a user to a path with a unique UUID when they go to the root URL (localhost:4200). However, I encountered the following error: ERROR Error: Uncaught (in promise): Error: Cannot match any routes. URL Segment: 'document/4fdb ...

Accessing file uploads in Angular 2

<div class="fileUpload btn btn-primary"> <span>Select File</span> <input id="uploadBtn" type="file" class="upload" value="No File Chosen" #uploadBtn/> </div> <input id="uploadFile" placeholder="No File Selected" disable ...

What's the best way in Angular 6 to set focus on an element that's being made content editable?

I am currently utilizing the contentEditable attribute in Angular 6 to allow for editing the content of elements within an ngFor loop. Is there a way to focus on a tag element when its contentEditable attribute is set to true? <div class="tag" *ngFor= ...

Avoiding redundant EventEmitters when transferring @Output to a child component

While working on a form component, I decided to separate the form action buttons into a child component. This led me to create two EventEmitter and handlers for the same action. I'm wondering if there is a way to directly pass the 'onDiscard&apo ...

Ensure that a particular key type is determined by the value of another key within the object (Utilizing Discriminated Unions)

The title of my question may not have been clear about what I am looking for, but what I need is something known as discriminated unions. You can find more information about it here: https://www.typescriptlang.org/docs/handbook/unions-and-intersections.htm ...

Implementing CSS styles according to user preferences. Switching between dark mode and light mode based on subscription

Is there a way to dynamically change CSS property values based on user interaction, such as toggling between dark mode and light mode? I am currently exploring the option of setting up a subscription to track these changes, but I want to know how I can act ...

Error loading ngs-boostrap in angular2: issues encountered during initialization

Attempting to implement a dropdown menu using ng2-bootstrap component, but encountering an error upon access: Error message received: Failed to load resource: the server responded with a status of 404 (Not Found) Steps taken so far: 1) Installed ng2-boo ...

Guide to simulating Twilio with Jest and TypeScript to perform unit testing

Please assist me in mocking a Twilio service that sends messages using Jest to mock the service. Below is the code I am working with: import { SQSEvent } from "aws-lambda"; import { GetSecretValueResponse } from "aws-sdk/clients/secretsmanag ...

Instructions on setting a photo as a background image using a text-based model

I'm a beginner with Angular so I may have a simple question. I am using an image from the Google API, which is not a URL. How can I set this image as the background-image in a CSS tag that only accepts URIs? Thank you! ...

When deploying my Angular project, I am unable to access my files

I have been facing challenges while trying to deploy my web application with the frontend being Angular. The issue I am encountering is that I cannot access my JSON file located in the assets folder. Below is the function I am using to retrieve data from ...

Exploring the depths of a TypeScript interface with unknown levels of complexity

My current challenge involves a recursive function that operates on an object with a generic interface. This function essentially traverses the object and creates a new one with a nearly identical interface, except for the leaf nodes which are transformed ...

Submit a pdf file created with html2pdf to an S3 bucket using form data

Currently, I have the following script: exportPDF(id) { const options = { filename: 'INV' + id + '.pdf', image: { type: 'jpeg', quality: 0.98 }, html2canvas: { scale: 2, dpi: 300, letterRendering: true, useC ...

Leverage the power of Angular 2 components within your Asp.net MVC

I am currently working on an Asp Mvc project which utilizes Angular 1.4 for the frontend. While my project is not designed to be a single page application, I am interested in incorporating Angular 2 without transitioning the entire project into a SPA. Aft ...

Ensure that X-frame-options is set to SAMEORIGIN in Angular 6 to prevent the website from being displayed within an iframe

My goal is to prevent my site from being displayed in an <iframe> tag. After doing some research, I learned that I need to set the 'x-frame-options' header to 'SAMEORIGIN'. I attempted to accomplish this by setting the meta tag a ...

Design an element that stretches across two navigation bars

Currently, I have implemented two Navbars on my website as shown in the image below: https://i.stack.imgur.com/4QmyW.png I am now looking to include a banner that clearly indicates that this site is a test site. In addition, I would like to incorporate a ...