Performing Jasmine unit testing on a component that relies on data from a service, which itself retrieves data from another service within an Angular 2+ application

Attempting to implement unit testing for a service using httpmock has been challenging. The service in question utilizes a method to make http get calls, but I have encountered difficulties in writing the test cases.

saveservice.service.ts -- file

const httpOptions = {
  headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};
const envURL = sessionStorage.getItem('apiBaseURL');
 httpGet<T>(url) {
    const URL = envURL + url;
    return this.http.get<T>(URL, httpOptions);
  }

The saveservice.service file contains the httpGET() method, which is utilized by work.service.ts.

work.service.ts

import {SaveserviceService } from '../../.././my-service.service';

getworklist(employeeID){

    return this.saveservice.httpGet('work/v1/works?employeeid=' + employeeID);
  }

This demonstrates the connection between workservice and save service. Now, the challenge lies in writing unit test cases for work.component.ts file with the implementation of httpmock.

For reference, the apiUrl is defined in a separate file called env.ts -- env.ts

export const apivalue= {

    apiBaseUrl:"https://example.co/",
  };

work.component.ts

ngOnit(){
this.employeeID:this.id;
   this.workservice.getworkList(this.employeeID).subscribe(
      (data) => {
        this.workList = data;
       console.log(" ggghfghfgh", this.worklist);
      }, (error) => {
        console.log(error);}

The above code snippet showcases work.component.ts file for which unit test cases need to be written. Assistance is required to accomplish this task.

work.component.spec.ts

 let httpMock: HttpTestingController;
 let injector: Injector;
  let workservice: WorksService;
let saveservice123: SaveService;

 providers: [
        Injector,
        HttpClient,
        HttpClientTestingModule,
        saveService,
        worksService
      ],

  httpMock = TestBed.get(HttpTestingController);
    workservice = TestBed.get(WorksService);
    saveservice123 = TestBed.get(SaveService)

  fit('getting work detsails indivually', async(() => {

    fixture = TestBed.createComponent(worksComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();

    workservice.getworkList(123).subscribe(() =>{});

    const request = httpMock.expectOne("work/v1/works?employeeid=")
    // expect(request.request.method).toBe('httpGet');
    // request.flush(xxxxx);

An error is being thrown:

Error: Expected one matching request for criteria "Match URL: work/v1/works?employeeGuid=", found none.

Assistance is needed on how to properly write unit test cases for this scenario. Attempts using spy have also proven unsuccessful.

const mockdata = { id:1, title: "Hello world",  paste: "console.log('Hello world');"}
     const spyOnAdd = spyOn(service, "getworkList").and.returnValue(mockdata);

Answer №1

Start by ensuring that your component includes the OnInit interface and that its ngOnint method is changed to ngOnInit.

When testing your component, focus on its behavior rather than the implementation of WorkService. This means mocking relevant parts of the WorkService for unit testing.

If the only parameter passed to the constructor of WorkService is SaveService, a basic example of work.component.spec.ts could be as follows:

import { ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
...

describe('WorkService', () => {

    const workList = [...]; // specify result of WorkService#getworklist
    const workService = new WorkService(null);
    let fixture: ComponentFixture<WorkComponent>;

    beforeEach(fakeAsync(() => {
        spyOn(workService , 'getworklist').and.returnValue(Promise.resolve(workList));
        TestBed.configureTestingModule({
            imports: [...],
            declarations: [WorkComponent],
            providers: [
                { provide: WorkService, useValue: workService }
            ]
        });
        fixture = TestBed.createComponent(WorkComponent);
        component = fixture.componentInstance;
        fixture.detectChanges();
        tick();
    }));

    it('getting work details individually', () => {
        expect(workService.getworklist).toHaveBeenCalled();
        expect(component.workList).toEqual(workList);
    });
});

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

The string is being added to an array twice

I am managing two sets of lists where strings will be transferred between them. One set contains a list of strings for searching purposes. The other set contains the same list of strings but is not used as a filter. The second set functions in a similar ...

Loading an Ionic module lazily within a children array is a smart way to

Within my Ionic application, I have structured a List Page Module and a Subdir Page Module nested under the main Page module. The folder structure looks like this ---> list/subdir. https://i.sstatic.net/XGrnU.png Dilemma: Whenever I navigate to localh ...

It's possible for anyone to enhance the appearance of the Download button by adding styles without compromising its functionality

Looking to enhance the style of the Download button as it appears too formal. Seeking assistance in adding some button styles to make it more stylish. The code is correct, just aiming to give the Download button a trendy look with specified styles. ...

Discover the simplicity of incorporating pagination into an HTML table with Angular Material

My goal is to implement pagination on my webpage, displaying 3 rows per page and enabling navigation through pages using Angular Material pagination. In usersComponent.ts, I retrieved data from an API: import { Component, OnInit, ViewChild } from '@an ...

Setting multiple dynamic values for select inputs in reactive forms can be achieved by following these steps

I am currently developing a dynamic select feature using reactive form in my project. So far, I have successfully implemented dynamic selects with the same values. However, I now have a requirement to load the dropdown values dynamically based on certain c ...

How do I manage two components on the same routing level in Angular with query parameters?

I am working with Angular and have two components placed at the same level of routing, both in the root directory. { path: '', component: HomeComponent }, { path: '', component: SearchComponent }, My challenge is to mak ...

Differences in characteristics of Javascript and Python

As I tackle an exam question involving the calculation of delta for put and call options using the Black and Scholes formula, I stumbled upon a helpful website . Upon inspecting their code, I discovered this specific function: getDelta: function(spot, str ...

"Track the progress of a form submission with a loading indicator using Sweet

I am looking to incorporate a waiting time animation when submitting a form, and I prefer using SweetAlert over a traditional loading image. Here is the basic code snippet: $("form").submit(function (e) { e.preventDefault(); // prevents def ...

Avoid using fs.read without returning a value to console.log

Seeking assistance with parsing a text file named information.txt and displaying the values using console.log. Here is the code snippet: fs.readFileSync("information.txt", "utf-8", function (err, data) { ...

Issue with OnChange event in HTML and Adding Content with Jquery

I'm currently working on an app that includes a dynamic dropdown feature using jQuery and the append() method to display changing numbers dynamically. Everything seems to be functioning well in the first field of the form, but when I try to add more f ...

The dreaded "fatal error: JavaScript heap out of memory" message struck once again while using npx

My attempt at setting up a boilerplate for a React app involved using the command npx create-react-app assessment D:\React>create-react-app assessment Creating a new React app in D:\React\assessment. Installing packages. This might take ...

Error: The function call does not match any of the overloads. 'VueRouter' is not recognized

I'm new to TypeScript and currently trying to implement vue-router in my project. Encountering the following errors: Error TS2769: No overload matches this call in source\app\main.ts(3,3). Overload 1 of 3, '(options?: ThisTypedCompon ...

When using Angular server-side pagination with ngrx and Express in Node.js, I often encounter discrepancies in the indexing across different stacks

After successfully implementing server-side pagination in Angular, I encountered an issue where the page was set to 1 initially, but the mat-paginator component started at index 2. Despite functioning correctly when changing pages, this discrepancy puzzled ...

Spotlight the flaw in the card's backbone using JS

What's the most effective method for emphasizing an error card view in backbone? Initially, I render 10 cards as UI where users input details in each card. Upon clicking submit, I validate all the details by parsing through collection->models. Curr ...

Issues with adjusting the height using CSS transformations are not being resolved

There seems to be an issue with animating the height property of an element as it is not animating at all. Check out the fiddle where the animation is attempted. Here is the HTML: <ul> <li> li 1 </li> <li> ...

Validating React Typescript Props: Ensuring that two specific props do not exist simultaneously

Currently, I'm developing a reusable component in React-Typescript and I am looking to validate my props OnClick and component as follows: Both onClick and component prop are optional. These props will only be passed to the component if they need to ...

OpenLayers had trouble handling the mouse event in Ionic

I am attempting to handle a double mouse click event on OpenStreetMaps by utilizing the code below: const map = new OpenLayers.Map("basicMap"); const mapnik = new OpenLayers.Layer.OSM(); const fromProjection = new OpenLayers.Projection("EPSG:4326"); // ...

transmit data from Node.js Express to Angular application

I am making a request to an OTP API from my Node.js application. The goal is to pass the response from the OTP API to my Angular app. Here is how the API service looks on Angular: sendOtp(params): Observable<any> { return this.apiService.post(&q ...

Updating a table dynamically after a form submission using jQuery, Ajax, and PHP without needing to refresh the page

My current setup involves an ajax form along with a table. Here is the ajax code I am using: $(function () { $(".submitann").click(function () { var title = $("#title").val(); var announcement = $("#announcement").val(); var d ...

What is the most efficient way to transfer form data from one JSP page to another?

I need to transfer information from one webpage (1.jsp) to another webpage (2.jsp). The data that needs to be transferred includes checkboxes, radio buttons, and drop downs. This data will be used in 2.jsp to generate the appropriate page. Is there a way ...