avishekdr
avishekdr

Reputation: 1068

How to read subscribe in Angular Unit Test?

I am trying to write test cases of a component where at first I tried to check if a basic test case is working or not. There I encountered some errors related to Dependency Injection and solved those. Now the first issue that I am facing is mocking the API calls.

Below is my component code for which I am writing test cases:

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { HttpClientService } from '@service/http-client.service';
import { CustomErrorStateMatcher } from '@validator/error-state-matcher';
import { ToastrService } from 'ngx-toastr';

@Component({
  selector: 'app-prep-card',
  templateUrl: './prep-card.component.html',
  styles: ['legend { width: fit-content !important; }']
})
export class PrepCardComponent implements OnInit {

  constructor(private fb: FormBuilder, private _http: HttpClientService, private toastr: ToastrService) { }
  
  foamTypeList: string[] = [];
  colorList: string[] = [];
   
  ngOnInit() { this.getFoam_ColorList() }

  private getFoam_ColorList() {
    this._http.getFoamType_ColorList('ABC').subscribe(response => {
      this.foamTypeList = response.data.foamTypesAndColors.foamTypes;
      this.colorList = response.data.foamTypesAndColors.colors;
    });
  }
}

At first, I tried to run a simple test case to check if it is working correctly or not. Below is the test case I wrote:

import { ComponentFixture, inject, TestBed } from "@angular/core/testing";
import { FormsModule, ReactiveFormsModule } from "@angular/forms";
import { RouterTestingModule } from '@angular/router/testing';
import { HttpClientService } from "@service/http-client.service";
import { ToastrService } from "ngx-toastr";
import { MaterialModule } from "src/app/material/material.module";
import { PrepCardComponent } from "./prep-card.component";

describe('PrepCardComponent', () => {
    let component: PrepCardComponent, fixture: ComponentFixture<PrepCardComponent>,
        _httpSpy: jasmine.SpyObj<HttpClientService>, _toastrSpy: jasmine.SpyObj<ToastrService>;

    beforeEach(async () => {
        const _httpSpyObj = jasmine.createSpyObj('HttpClientService', ['getFoamType_ColorList']),
            _toastrSpyObj = jasmine.createSpyObj('ToastrService', ['success', 'error']);

        await TestBed.configureTestingModule({
            declarations: [PrepCardComponent],
            imports: [
                RouterTestingModule, FormsModule, ReactiveFormsModule, MaterialModule
            ],
            providers: [
                { provide: HttpClientService, useValue: _httpSpyObj },
                { provide: ToastrService, useValue: _toastrSpyObj },
            ]
        }).compileComponents();
        fixture = TestBed.createComponent(PrepCardComponent);
        component = fixture.componentInstance;
        fixture.detectChanges();
    });

    it('test', () => expect('a').toBe('a'));
});

The above code snippet threw the following error:

TypeError: Cannot read properties of undefined (reading 'subscribe') at PrepCardComponent.getFoam_ColorList (http://localhost:9876/karma_webpack/webpack:/src/app/pages/prep-card/prep-card.component.ts:57:52) at PrepCardComponent.setFormFieldValidator (http://localhost:9876/karma_webpack/webpack:/src/app/pages/prep-card/prep-card.component.ts:65:10) at PrepCardComponent.createForm (http://localhost:9876/karma_webpack/webpack:/src/app/pages/prep-card/prep-card.component.ts:48:10) at PrepCardComponent.ngOnInit (http://localhost:9876/karma_webpack/webpack:/src/app/pages/prep-card/prep-card.component.ts:28:10) at callHook (http://localhost:9876/karma_webpack/webpack:/node_modules/@angular/core/fesm2015/core.mjs:2542:1) at callHooks (http://localhost:9876/karma_webpack/webpack:/node_modules/@angular/core/fesm2015/core.mjs:2511:1) at executeInitAndCheckHooks (http://localhost:9876/karma_webpack/webpack:/node_modules/@angular/core/fesm2015/core.mjs:2462:1) at refreshView (http://localhost:9876/karma_webpack/webpack:/node_modules/@angular/core/fesm2015/core.mjs:9499:1) at renderComponentOrTemplate (http://localhost:9876/karma_webpack/webpack:/node_modules/@angular/core/fesm2015/core.mjs:9598:1) at tickRootContext (http://localhost:9876/karma_webpack/webpack:/node_modules/@angular/core/fesm2015/core.mjs:10829:1)

To solve this, I searched different questions here and saw common solution mentioned below to get an observable.

it('Call Service', inject([HttpClientService], (_http: HttpClientService) => {
    spyOn(_http, 'getFoamType_ColorList').and.returnValue({subscribe: () => {}})
}));

Writing the above test case was throwing an error (mentioned below) in the subscribe position.

Type 'void' is not assignable to type 'Subscription'.ts(2322)

Service code

getFoamType_ColorList(cardType: string) {
  return this.http.get<{ message: string, data: { foamTypesAndColors: { foamTypes: string[], colors: string[] } } }>
    (`${this.URL}/validate/foam-type-and-color/${cardType}`);
}

Can anyone help me out with how I can solve this issue?

UPDATE

As per dmance's answer am not getting any error while writing the test case but the test cases are still failing giving the same error. For reference refer below the full error log:

error

Upvotes: 0

Views: 2851

Answers (2)

dmance
dmance

Reputation: 668

I will suggest this:

import { of } from 'rxjs';
spyOn(httpclientservice, 'getFoamType_ColorList').and.returnValue(of(YOUR VALUE));

This is a more complete answer:

describe('PrepCardComponent', () => {
    let component: PrepCardComponent, fixture: ComponentFixture<PrepCardComponent>;
    let httpClientService: HttpClientService;
    let toastService: ToastrService;

    beforeEach(async () => {
        await TestBed.configureTestingModule({
            declarations: [PrepCardComponent],
            imports: [
                RouterTestingModule, FormsModule, ReactiveFormsModule, MaterialModule
            ]
        }).compileComponents();
        httpClientService = TestBed.inject(HttpClientService);
        toastService= TestBed.inject(ToastrService);

        fixture = TestBed.createComponent(PrepCardComponent);
        component = fixture.componentInstance;
        fixture.detectChanges();
    });

    it('test', () => {
        spyOn(httpClientService, 'getFoamType_ColorList').then.returnValue(of(YOUR VALUE));
        // MAKE YOUR TEST
    });
});

Upvotes: 3

Sascha Liebmann
Sascha Liebmann

Reputation: 31

Try this maybe

spyOn(_http,'getFoamType_ColorList').and.returnValue(Observable.of(Your_Value));

Upvotes: 0

Related Questions