Alek Aleksandrov
Alek Aleksandrov

Reputation: 58

Fixture.detectChanges() is undefined; Angular 5 Unit Test

I am trying to run a basic unit test on a pretty simple component.

Component

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';

import { CmsService } from '../services/cms.service';

@Component({
  selector: 'app-balance',
  templateUrl: './balance.component.html',
  styleUrls: ['./balance.component.css']
})

export class BalanceComponent implements OnInit {
  data;
  balance;

  constructor(private router: Router, private service: CmsService) {
    this.data = this.service.getData();
    this.balance = this.data['balance'];
  }

  ngOnInit() {
  }
}

Spec File

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

import { BalanceComponent } from './balance.component';
import { RouterTestingModule } from '@angular/router/testing';
import { CmsService } from '../services/cms.service';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { HeaderComponent } from '../header/header.component';
import { FooterComponent } from '../footer/footer.component';
import { SidebarComponent } from '../sidebar/sidebar.component';
import { MessagesComponent } from '../messages/messages.component';
import { KeysPipe } from '../../../paysign-angular-common/lib/src/pipes/keys.pipe';

fdescribe('BalanceComponent', () => {
  let component: BalanceComponent;
  let fixture: ComponentFixture<BalanceComponent>;
  let service: CmsService;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ BalanceComponent, HeaderComponent, FooterComponent, SidebarComponent, MessagesComponent, KeysPipe ],
      providers: [ CmsService ],
      imports: [ RouterTestingModule, HttpClientTestingModule ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(BalanceComponent);
    component = fixture.componentInstance;
    service = TestBed.get(CmsService);
    spyOn(service, 'getData').and.returnValue({balance: 50.00});

  });

  // it('should make a call to getData on load', async(() => {

  // }));

  it('should create with a balance avaliable in the session', () => {
    fixture.detectChanges();
    sessionStorage.setItem('data', JSON.stringify({balance: 50.00}));
    spyOn(service, 'getData').and.callFake(() => {
      return sessionStorage.getItem('data');
    });
    component.data = service.getData();
    expect(component.balance).toEqual(50.00);
    expect(component).toBeTruthy();
    sessionStorage.clear();
  });
});

The main issue is when the test is run, fixture is undefined. The stack trace is:

TypeError: Cannot read property 'detectChanges' of undefined
    at UserContext.<anonymous> (http://localhost:9876/_karma_webpack_/webpack:/C:/Users/aaleksandrov/Documents/Paysign-Kiosk-client/src/app/balance/balance.component.spec.ts:40:13)
    at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/webpack:/C:/Users/aaleksandrov/Documents/Paysign-Kiosk-client/node_modules/zone.js/dist/zone.js:388:1)
    at ProxyZoneSpec.webpackJsonp.../../../../zone.js/dist/zone-testing.js.ProxyZoneSpec.onInvoke (http://localhost:9876/_karma_webpack_/webpack:/C:/Users/aaleksandrov/Documents/Paysign-Kiosk-client/node_modules/zone.js/dist/zone-testing.js:288:1)
    at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/webpack:/C:/Users/aaleksandrov/Documents/Paysign-Kiosk-client/node_modules/zone.js/dist/zone.js:387:1)
    at Zone.webpackJsonp.../../../../zone.js/dist/zone.js.Zone.run (http://localhost:9876/_karma_webpack_/webpack:/C:/Users/aaleksandrov/Documents/Paysign-Kiosk-client/node_modules/zone.js/dist/zone.js:138:1)
    at runInTestZone (http://localhost:9876/_karma_webpack_/webpack:/C:/Users/aaleksandrov/Documents/Paysign-Kiosk-client/node_modules/zone.js/dist/zone-testing.js:509:1)
    at UserContext.<anonymous> (http://localhost:9876/_karma_webpack_/webpack:/C:/Users/aaleksandrov/Documents/Paysign-Kiosk-client/node_modules/zone.js/dist/zone-testing.js:524:1)
    at attempt (http://localhost:9876/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?73bc53d3671677e6a093fc74e4f9bcde57e5f7ad:4289:46)
    at ZoneQueueRunner.QueueRunner.run (http://localhost:9876/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?73bc53d3671677e6a093fc74e4f9bcde57e5f7ad:4217:20)
    at runNext (http://localhost:9876/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?73bc53d3671677e6a093fc74e4f9bcde57e5f7ad:4257:20)

Which does not happen if I move the fixture creation outside of the beforeEach. I have tried moving it into the async block, but I've run out of ideas.

Edit: Looking into it more reveals that TestBed itself is giving a Reference error anywhere its called.

Upvotes: 2

Views: 9037

Answers (1)

A. Figueroa
A. Figueroa

Reputation: 225

I used your code to try to help you debug, but I couldnt reproduce. I removed all elements not related to the use of Fixture.detectChanges(). Here's the code I ran and succeeded.

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

import { BalanceComponent } from './balance.component';
import { RouterTestingModule } from '@angular/router/testing';
import { HttpClientTestingModule } from '@angular/common/http/testing';

fdescribe('BalanceComponent', () => {
  let component: BalanceComponent;
  let fixture: ComponentFixture<BalanceComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ BalanceComponent ],
      imports: [ RouterTestingModule, HttpClientTestingModule ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(BalanceComponent);
    component = fixture.componentInstance;
  });

  // it('should make a call to getData on load', async(() => {

  // }));

  it('should create with a balance avaliable in the session', () => {
    fixture.detectChanges();
    expect(component).toBeTruthy();
  });
});

enter image description here

My guess, is that you're using outdated Jasimne/Karma npm packages that may declare Fixture differently. Could you post your package.json so I can take a look please?

Upvotes: 3

Related Questions