Simulating HTTP requests in Angular Testing

I'm in the process of writing unit tests for my Angular application. I need to mock the data returned by a service for HTTP calls.

component.spec.ts

let apiService: ApiService;
let mockedHttpClient: HttpClient = mock(HttpClient);

beforeEach(async () => {
  await TestBed.configureTestingModule({
    declarations: [EditorComponent],
    providers: [
      { provide: ApiService, useValue: apiService },
      {
        provide: HttpClient,
        useFactory: () => instance(mockedHttpClient),
      },
    ],
    imports: [HttpClientModule],
  }).compileComponents();
});

beforeEach(() => {
  apiService = TestBed.inject(ApiService);

  fixture = TestBed.createComponent(EditorComponent);
  component = fixture.componentInstance;

  fixture.detectChanges();
});

it("should retrieve information", (done: DoneFn) => {
  component.id = "id1";
  spyOn(apiService, "getInfosById").and.returnValue(of(infos));

  component.getInformations();

  expect(component.infos).toEqual(infos);
});

component.ts

private readonly unsubscribe = new Subject();

getInformations() {
   this.apiService
      .getInfos(this.id)
      .pipe(takeUntil(this.unsubscribe))
      .subscribe((data) => {
        this.infos = data;
   })
}

ngOnDestroy() {
    this.unsubscribe.next();
    this.unsubscribe.complete();
  }

api-service.ts

public getInfos(id: string) {
    return this.http.get<Infos>(
              this.apiUrl +'infos/' + id,
              httpOptions)}

I'm looking to mock the function mentioned above.

Error

<spyOn> : could not find an object to spy upon for getInformations()

What could be the issue here? Are there better ways to mock an HTTP service with .pipe and .subscribe?

Answer №1

When simulating the response of an HTTP call, I typically create a mock API service like this:

@Injectable()
class MockApiService extends ApiService {
  getInfos(): any {
     const data = {} // Customize the object based on expected response
     return data;
  }
}

beforeEach(async () => {
        await TestBed.configureTestingModule({
          declarations: [EditorComponent],
          providers: [
             <!------- Don't forget to add the line below -----!>
            { provide: ApiService, useClass: MockApiService },
            {
              provide: HttpClient,
              useFactory: () => instance(mockedHttpClient),
    
            },    
          ],
          imports: [
            HttpClientModule
          ]
        })
          .compileComponents();
      });

it('should execute #getInformations() method in component', () => {
  spyOn(component, 'getInformations').and.callThrough();
  component.getInformations();
  expect(component.getInformations).toHaveBeenCalled();
});

// This test case validates the successful execution of the service call

Answer №2

Appreciate the assistance provided in solving my initial problem. Now, I am looking to delve deeper into the solution. Instead of testing HTTP itself (which has been done), I am interested in mocking the results of a service. While it works fine for one method, encountering issues when attempting multiple methods concurrently.

fit("should get getDesignerInformations", (done: DoneFn) => {


    spyOn(apiService1,'getInfo').and.returnValue(of(infoMock)); <-- this one works
    spyOn(apiService2, 'getProduct').and.returnValue(of(productMock));<-- this one doesn't work
}

The first call gets mocked successfully, but the second one seems to disappear after the first call is made.

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

Encountering an Error with PrimeNG dataTable when Using a p-checkbox within a p-column

My Datatable is currently functioning properly: <p-dataTable [value]="myObjects" [rows]="10" [paginator]="true" [pageLinks]="3"> <p-column field="name" header="Name"></p-column> <p-column field="size" header="Size"></p-c ...

Issues encountered when attempting to use ngModel within ngFor (Angular version 5.1.2)

Encountering some unusual behavior with the combination of ngFor and ngModel. Allow me to illustrate with an example: heroes = [ { "name": "Deadpool" }, { "name": "Thor" }, { "name": "Superman" }, { "name": "Ba ...

Facing difficulties in Angular 8 while trying to import firestore and firebase for an authentication system

While attempting to implement Firestore/Firebase functionalities for Google OAuth signin, I encountered an error indicating that Firebase is not imported: https://i.sstatic.net/oL4rY.png CODE: ERROR in node_modules/@angular/fire/auth/auth.d.ts:4:28 - er ...

What is the most effective method for obtaining the ViewContainerRef of a mat-row in Angular 4

I am currently working with a mat-table and I'm looking to retrieve the ViewContainerRef of a clicked row in order to add another component within that specific row. Can anyone suggest the most effective method to obtain the ViewContainerRef of a row? ...

Clearing Out a Shopping Cart in Angular

Hey there, I have a little dilemma with my shopping cart system. I can easily add and delete products using an API. However, when it comes to deleting an item from the cart, I have to do it one by one by clicking on a button for each item, which is not ver ...

React Error: Attempting to access the 'style' property of an undefined object

Can anyone help with this issue related to React code? const sidebar = document.getElementsByClassName("pro-sidebar"); The problem occurs when trying to adjust the width using: function openNav() { sidebar.style.width = "250px";} Addi ...

Learn how to mock asynchronous calls in JavaScript unit testing using Jest

I recently transitioned from Java to TypeScript and am trying to find the equivalent of java junit(Mockito) in TypeScript. In junit, we can define the behavior of dependencies and return responses based on test case demands. Is there a similar way to do t ...

What is the best way to verify the presence of a route in Angular with Jasmine testing framework?

I'm currently in the process of developing a test to verify the presence of a specific route within my Angular application using Jasmine: import { routes } from './app-routing.module'; import { UsersComponent } from './users/users.comp ...

Is there a way for me to bypass adding the label if it already exists in my state, but still include the new value?

I am currently facing an issue with a dropdown select field where I can choose various attribute values. The problem arises when attempting to save the selected data in the state, as the label appears twice and I only require it once. My goal is to exclude ...

The combination of Material UI and React Hook Form is encountering an issue with submitting disabled checkboxes

My current challenge involves ensuring that all fields are disabled while the form is submitting. I have successfully implemented this for text, selects, and radios, but I am facing difficulties with required checkboxes. I am working with nextjs typescrip ...

Unraveling the art of utilizing the map operator in ES6 with condition

I need to implement a condition within the map function where I prepend zeros for single digit values (00.00 to 09.30), while leaving remaining values unchanged. Currently, it is prepending zeros for all values. Here is the code: export class SelectOver ...

React TypeScript error: Cannot access property "x" on object of type 'A | B'

Just starting out with react typescript and I've encountered the following typescript error when creating components: interface APIResponseA { a:string[]; b:number; c: string | null; // <- } interface APIResponseB { a:string[] | null; b:number; d: ...

Creating a dynamic form in Angular using reactive forms and form builder that pulls real-time data from the server

I have been struggling for the past two days to organize the data in the correct order but so far, I haven't been successful. Essentially, I retrieve some data from the server and present it to the client along with additional fields that the client n ...

Combining and mapping arrays in Javascript to form a single object

I am using the following firebase function this.sensorService.getTest() .snapshotChanges() .pipe( map(actions => actions.map(a => ({ [a.payload.key]: a.payload.val() }))) ).subscribe(sensors => { ...

Ways to initiate a fresh API request while utilizing httpClient and shareReplay

I have implemented a configuration to share the replay of my httpClient request among multiple components. Here is the setup: apicaller.service.ts import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http& ...

What sets apart ".. let i = index" from "..let i as index"?

Having recently delved into the world of Angular, I've been scouring YouTube for tutorials. While watching, I noticed some developers using ""let item of items; let i as index"" while others used ""let item of items; let i = index" ...

"Encountering issues with DefinePlugin when using the combination of Ionic, Angular, Webpack,

I'm trying to incorporate my process.env variable into the webpack Bundle using DefinePlugin. Here's the snippet of code in my webpack config: plugins: [ new webpack.DefinePlugin({ 'process.env': JSON.stringify(process.env) ...

Typescript - Troubleshooting undefined error with static variables

My node API app is developed using express and typescript. The static variable of the Configuration Class is initialized with required configuration before starting the server. However, when I try to use this static variable in a separate TypeScript class ...

The attribute 'commentText' is not found within the 'Comment' data type

Currently, I am immersed in building a user-friendly social network application using Angular 12 for my personal educational journey. Running into an error has left me puzzled and looking for assistance. About the Application: The home page (home.compone ...

What could be causing useFormik to automatically update the initial value?

I have a component structure that looks like this. Please note that the actual code may differ from this, but this is to help you visualize. <EditAssessment> <AssessmentForm> <AssessmentScheduleCronWeekField> </Asses ...