Cannot read property 'injector' of null jasmine angular 2
Asked Answered
C

1

9

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.

Citriculture answered 20/11, 2016 at 1:3 Comment(0)
F
17

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());
});
Felicity answered 20/11, 2016 at 1:27 Comment(7)
Thanks. I'm just experiencing this error now: file:app/landing-page/subcomponents/middle-row.component.spec.ts' severity: 'Error' message: 'Argument of type '(extraProviders?: Provider[]) => PlatformRef' is not assignable to parameter of type 'PlatformRef'. Property 'bootstrapModuleFactory' is missing in type '(extraProviders?: Provider[]) => PlatformRef'.' at: '26,34' source: 'ts' I must be needing to add something to my bootstrap of the app? platformBrowserDynamic().bootstrapModule(AppModule);?Citriculture
Sorry, the second arg should be a method call, not just the method. I fixed itFelicity
It is probably the solution, I'm just trying to get another issue sorted out so that I can verify that it worked. Some weird stuff is happening when I import test classes from @angular. Thanks.Citriculture
beforeAll is not defined :P Sorry my environment must be terribly UNset up for testing. I'm trying to sort out this issue. Seems like it's usually due to an old version of Jasmine however in my package.json devDependencies I have "jasmine": "~2.0.0",, and I deleted node_modules and did a clean installCitriculture
Really you could just put it before the describe. It doesn't need to be in a beforeall. You could even put it in beforeeach, but it might lead to bad performance in the testsFelicity
Really you should just look into using the testshim file like the one I linked to I. The quickstartFelicity
I knew there was a correct solution on one of my questions I was forgetting about!Citriculture

© 2022 - 2024 — McMap. All rights reserved.