Karma + Jasmine: Cannot read property 'getComponentFromError'
Asked Answered
B

3

13

I am following this tutorial: https://angular.io/guide/testing#component-test-scenarios for karma+jasmine unit testing. Here my code:

import { AppComponent } from "./app.component";
import { ComponentFixture, TestBed } from "@angular/core/testing";

describe('AppComponent', () => {

let component: AppComponent;
let fixture:   ComponentFixture<AppComponent>;
let h1:        HTMLElement;

beforeEach(() => {
  TestBed.configureTestingModule({
    declarations: [ AppComponent ],
  });
  fixture = TestBed.createComponent(AppComponent);
  component = fixture.componentInstance; 
  h1 = fixture.nativeElement.querySelector('h1');
});

it('should display original title', () => {
    expect(h1.textContent).toContain("Ciao");
  });

});

When I run the test I get the following exception:

 TypeError: Cannot read property 'getComponentFromError' of null
    at TestBed._initIfNeeded (D:/Users/apwzp/AppData/Local/Temp/karma-typescript-bundle-11944DDd01l2f5Y0P.js:1020:52)
    at TestBed.createComponent (D:/Users/apwzp/AppData/Local/Temp/karma-typescript-bundle-11944DDd01l2f5Y0P.js:1174:14)
    at Function.TestBed.createComponent (D:/Users/apwzp/AppData/Local/Temp/karma-typescript-bundle-11944DDd01l2f5Y0P.js:876:29)
    at UserContext.<anonymous> (assets/app/app.component.spec.ts:14:20 <- assets/app/app.component.spec.js:13:37)
    at ZoneDelegate.invoke (node_modules/zone.js/dist/zone.js:388:26)
    at ProxyZoneSpec.onInvoke (node_modules/zone.js/dist/proxy.js:79:39)
    at ZoneDelegate.invoke (node_modules/zone.js/dist/zone.js:387:32)
    at Zone.run (node_modules/zone.js/dist/zone.js:138:43)
    at UserContext.<anonymous> (node_modules/zone.js/dist/jasmine-patch.js:106:34)

Does anyone know how to solve it?

Babbler answered 2/3, 2018 at 11:15 Comment(0)
W
26

I ran into something similar and found the answer here: Cannot read property 'injector' of null jasmine angular 2.

I just added this to my beforeEach() method which solved this error for me (there were a few others I had to overcome before I got this all working entirely).

 TestBed.resetTestEnvironment();
 TestBed.initTestEnvironment(BrowserDynamicTestingModule,
    platformBrowserDynamicTesting());

Basically it was just a matter of changing this:

beforeEach(() => {
  TestBed.configureTestingModule({
    declarations: [ AppComponent ],
   });
  fixture = TestBed.createComponent(AppComponent);
  component = fixture.componentInstance; 
  h1 = fixture.nativeElement.querySelector('h1');
});

To

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

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

  TestBed.configureTestingModule({
    declarations: [ AppComponent ],
   });
  fixture = TestBed.createComponent(AppComponent);
  component = fixture.componentInstance; 
  h1 = fixture.nativeElement.querySelector('h1');
});
Wulf answered 8/3, 2018 at 1:23 Comment(6)
That fixed it... but why...? I already had a call to TestBed.initTestEnvironment() in a different file and made sure that file is loaded before my spec.ts files. Why does moving the init code to the .spec.ts file fix this error?Anikaanil
The key here is initTestEnvironment which per the angular docs is required to initialize the compiler, platformRef and angular module for testing. Not sure about having to move the files around. I found this worked for me provided it is inside every files beforeEach or beforeAll.Wulf
I already had initTestEnvironment but it was in a different file. I even made sure that file was loaded before my specs. Nothing worked except this answer.Anikaanil
I'm not entirely sure I'm answering your question but; initTestEnvironment needs to be run in a beforeEach or beforeAll in every .spec file in order to prepare the Angular environment. You can't just run it once before your specs load.Wulf
Well why can't I just run it once before my specs load? What does it do that only works if run inside beforeAll? That's the part that I don't understand.Anikaanil
I am not sure with this answer. Because in all my tests until now, I had no issues running tests without resetting my test environment and initing the browser dynamic testing. Adding this code, did not fix my issues.Contain
C
1

If you're upgrading to jest-preset-angular version >= 9, replacing import 'jest-preset-angular'; with import 'jest-preset-angular/setup-jest'; seems to solve the issue without the need to add a beforeAll to every test.

See https://github.com/thymikee/jest-preset-angular/blob/a4251dd9776fe4d99af828b43acc3ea3a1bb5f90/CHANGELOG.md#breaking-changes

Comfort answered 13/8, 2021 at 11:47 Comment(0)
B
0

Just add this to setupJest.ts in the root folder:

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

TestBed.resetTestEnvironment();
TestBed.initTestEnvironment(BrowserDynamicTestingModule,
  platformBrowserDynamicTesting());

And then add this to the jest configuration:

"setupFilesAfterEnv": [
  "<rootDir>/setupJest.ts"
],
Beberg answered 4/2, 2022 at 15:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.