Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

380
Views
Initialization of TestBed for Angular with Karma

I have a working setup with Karma for an Angular application. Currently I'm testing 2 different services PerformanceService and DataService, so I have 2 files, performance.service.spec.ts and data.service.spec.ts

Both files are initializing the TestBed and also configuring a MockHttp to use when testing the services.

TestBed.initTestEnvironment(
  BrowserDynamicTestingModule,
  platformBrowserDynamicTesting()
);

function createResponse(body) {
  return Observable.of(
    new Response(new ResponseOptions({ body: JSON.stringify(body) }))
  );
}

class MockHttp {
  get() {
    return createResponse([]);
  }
}

As far as I know, this can be done once, no need to do it for every single service, so I created a src/main.spec.ts and moved that code there, and removed it from the services.

Now I run the tests and it doesn´t work, I get an error TypeError: Cannot read property 'injector' of null

Any idea why this happens? The main.spec.ts is being executed first, so if I'm not mistaken TestBed should be initialized once we get to test the services.

Thanks

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

Just want to add to the answer of bobbyg603

For jest users - just add the following code in setup-jest.js

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

TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
over 4 years ago · Santiago Trujillo Report

0

Our team ran into the same problem. One solution is to extract the TestBed initialization into a separate file and guard it so that it only gets initialized once:

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

export class TestBedInitializer {

    static isInitialized: Boolean = false;

    static getTestBed() {
        if(!this.isInitialized) {
            TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
            this.isInitialized = true;
        }

        return TestBed;
    }
}

Then you can use the initializer in the beforeAll block to get the instance of TestBed:

import { TestBedInitializer } from './init';

describe('YourSystemUnderTest', () => {

    let TestBed;

    beforeAll(() => {
        TestBed = TestBedInitializer.getTestBed();
    });

    beforeEach(() => TestBed.configureTestingModule({
        imports: [...],
        providers: [...]
    }));

    ...

});

The advantage to this solution is that you're not dependent on your test suites running in any particular order. This frees you up to run your suites individually or all at once without needing to make code changes.

over 4 years ago · Santiago Trujillo Report

0

There is no need to create your own MockHttp class, as Angular has already created one: https://angular.io/docs/ts/latest/api/http/testing/index/MockBackend-class.html

An example usage would be something like this:

describe( 'AppleService', () => {
    let appleService: AppleService,
        response: Response;

    beforeEach( () => {
        TestBed.configureTestingModule( {
            providers: [
                AppleService,
                { provide: XHRBackend, useClass: MockBackend },
                { provide: ComponentFixtureAutoDetect, useValue: true }
            ],
            imports: [
                HttpModule
            ]
        } )
        .compileComponents();
    } );

    it( 'getApples() should return mocked results', async(
        inject( [ Http, XHRBackend ], ( http: Http, backend: MockBackend ) => {
            backend.connections.subscribe( ( connection: MockConnection ) => {
                expect( connection.request.url.match( /\/apple$/ ) ).not.toBe( null );
                expect( connection.request.method ).toBe( RequestMethod.Get );
                connection.mockRespond( response );
            } );

            let options = new ResponseOptions( { status: 200, body: [ testApple1, testApple2 ] } );
            response = new Response( options );

            appleService = new AppleService( resourceService, http );

            appleService.getApples().subscribe( apples => {
                expect( apples ).toEqual( [ testApple1, testApple2 ] );
            } );
    } ) ) );

} );

TestBed.get() can also be used instead of the inject() wrapper.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!