Search code examples
jasminekarma-runner

TypeError: Cannot read properties of undefined (reading 'subscribe') in Jasmine


I am trying to write the test cases for the below method :-

 subscriptionPackages() {
    this.managePackageService.getPackages().subscribe(
      (response) => {
        this.packagePlan = response;
      },
      (httpErrorRes) => {
      }
    );
  }

I have tried the below snippet in my spec.ts file for covering the above code :-

  fdescribe('AddProductComponent', () => {
  let component: AddProductComponent;
  let fixture: ComponentFixture<AddProductComponent>;
  let packageServiceStub = jasmine.createSpyObj('ManagePackageService', ['getPackages']);

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [HttpClientTestingModule,ReactiveFormsModule,FormsModule,ToastrModule.forRoot(),
        TranslateModule.forRoot(), NgSelectModule],
      declarations: [ AddProductComponent ],
      providers :[AppConfig,
        { provide: ManagePackageService, useValue: packageServiceStub }]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(AddProductComponent);
    component = fixture.componentInstance;
    component.packagePlan = [{'name':'basic', 'id':1}, {'name':'advance', 'id':2}, {'name':'premium', 'id':3}];
    fixture.detectChanges();
  });

it('should create  subscriptionPackages', () => {
  const mockpackageResponse = []; 
  packageServiceStub.getPackages.and.returnValue(of(mockpackageResponse));
  component.subscriptionPackages();
  expect(component.packagePlan).toBeTruthy();
 });

From this code my test case is covered but I am getting below error :-

enter image description here


Solution

  • Do you call subscriptionPackages in the ngOnInit or the constructor of the component?

    If you're calling it in the ngOnInit, you need to mock the returnValue before the first fixture.detectChanges(). The first fixture.detectChanges() is when ngOnInit is called.

    beforeEach(() => {
        fixture = TestBed.createComponent(AddProductComponent);
        component = fixture.componentInstance;
        // !! Move this line here if calling subscriptionPackages in ngOnInit !!
        packageServiceStub.getPackages.and.returnValue(of(mockpackageResponse));
        component.packagePlan = [{'name':'basic', 'id':1}, {'name':'advance', 'id':2}, {'name':'premium', 'id':3}];
        fixture.detectChanges();
      });
    
    it('should create  subscriptionPackages', () => {
      const mockpackageResponse = []; 
      component.subscriptionPackages();
      expect(component.packagePlan).toBeTruthy();
     });
    
    beforeEach(() => {
         // !! Move this line here if calling subscriptionPackages in constructor !!
        packageServiceStub.getPackages.and.returnValue(of(mockpackageResponse));
        fixture = TestBed.createComponent(AddProductComponent);
        component = fixture.componentInstance;
        component.packagePlan = [{'name':'basic', 'id':1}, {'name':'advance', 'id':2}, {'name':'premium', 'id':3}];
        fixture.detectChanges();
      });
    
    it('should create  subscriptionPackages', () => {
      const mockpackageResponse = []; 
      component.subscriptionPackages();
      expect(component.packagePlan).toBeTruthy();
     });