Cannot read property 'injector' of null jasmine angular 2

BeniaminoBaggins picture BeniaminoBaggins · Nov 20, 2016 · Viewed 10.2k times · Source

I'm getting this error when running a jasmine spec in angular 2:

Cannot read property 'injector' of null jasmine angular 2

stack trace:

TypeError: Cannot read property 'injector' of null
    at TestBed._createCompilerAndModule (http://localhost:3002/node_modules/@angular/core/bundles/core-testing.umd.js:834:48)
    at TestBed._initIfNeeded (http://localhost:3002/node_modules/@angular/core/bundles/core-testing.umd.js:800:43)
    at TestBed.createComponent (http://localhost:3002/node_modules/@angular/core/bundles/core-testing.umd.js:884:18)
    at Function.TestBed.createComponent (http://localhost:3002/node_modules/@angular/core/bundles/core-testing.umd.js:714:33)
    at Object.eval (http://localhost:3002/js/app/landing-page/subcomponents/middle-row.component.spec.js:29:49)
    at ZoneDelegate.invoke (http://localhost:3002/node_modules/zone.js/dist/zone.js:232:26)
    at ProxyZoneSpec.onInvoke (http://localhost:3002/node_modules/zone.js/dist/proxy.js:79:39)
    at ZoneDelegate.invoke (http://localhost:3002/node_modules/zone.js/dist/zone.js:231:32)
    at Zone.run (http://localhost:3002/node_modules/zone.js/dist/zone.js:114:43)
    at Object.eval (http://localhost:3002/node_modules/zone.js/dist/jasmine-patch.js:102:34)

I have copied this spec from the official angular 2 testing docs:

let comp:    BannerComponent;
let fixture: ComponentFixture<BannerComponent>;
let de:      DebugElement;
let el:      HTMLElement;

describe('BannerComponent', () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [ BannerComponent ], // declare the test component
    });

    fixture = TestBed.createComponent(BannerComponent);

    comp = fixture.componentInstance; // BannerComponent test instance

    // query for the title <h1> by CSS element selector
    de = fixture.debugElement.query(By.css('h1'));
    el = de.nativeElement;

  });
});

and adapted it ever so slightly to work with my code:

import 'zone.js/dist/long-stack-trace-zone.js';
import 'zone.js/dist/async-test.js';
import 'zone.js/dist/fake-async-test.js';
import 'zone.js/dist/sync-test.js';
import 'zone.js/dist/proxy.js';
import 'zone.js/dist/jasmine-patch.js';

import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';

import { MiddleRowComponent } from './middle-row.component';

let comp: MiddleRowComponent;
let fixture: ComponentFixture<MiddleRowComponent>;
let de: DebugElement;
let el: HTMLElement;

describe('MiddleRowComponent', () => {
   beforeEach(() => {
      TestBed.configureTestingModule({
         declarations: [MiddleRowComponent], // declare the test component
      });

      fixture = TestBed.createComponent(MiddleRowComponent);

      comp = fixture.componentInstance; // MiddleRowComponent test instance

      // query for the title <h1> by CSS element selector
      de = fixture.debugElement.query(By.css('h1'));
      el = de.nativeElement;
   });

   it('should display original title', () => {
      fixture.detectChanges();
      expect(el.textContent).toContain(comp.word);
   });

   it('should display a different test title', () => {
      comp.word = 'Test Title';
      fixture.detectChanges();
      expect(el.textContent).toContain('Test Title');
   });
});

Why am I getting the error? There is no inject keyword but I guess the TestBed might use it behind the scenes.

Answer

Paul Samsotha picture Paul Samsotha · Nov 20, 2016

At some point (prior to any tests being executed) you need to initial the testing environment, by calling TestBed.initTestEnvironment(...).

You would normally see this done in a karma-test-shim file, as seen in the angular quickstart (same quickstart from testing docs). But if you're not using this technique, then you need to do this in your test files. But the initTestEnvironment should only be called once, so you need to also reset it in each test file

import { BrowserDynamicTestingModule,
         platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';

beforeAll(() => {
  TestBed.resetTestEnvironment();
  TestBed.initTestEnvironment(BrowserDynamicTestingModule,
                              platformBrowserDynamicTesting());
});