用Karma初始化角度的TestBed

时间:2017-04-28 10:12:32

标签: angular karma-runner

我在Karma上有一个Angular应用程序的工作设置。目前我正在测试2个不同的服务PerformanceService和DataService,所以我有2个文件,performance.service.spec.ts和data.service.spec.ts

两个文件都在初始化TestBed,并且还配置了在测试服务时使用的MockHttp。

TestBed.initTestEnvironment(
  BrowserDynamicTestingModule,
  platformBrowserDynamicTesting()
);

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

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

据我所知,这可以做一次,不需要为每一项服务都做,所以我创建了一个src / main.spec.ts并将那些代码移到那里,并将其从服务中删除。 / p>

现在我运行测试并且它不起作用,我收到错误TypeError: Cannot read property 'injector' of null

知道为什么会这样吗? main.spec.ts首先被执行,所以如果我没有弄错的话,一旦我们测试服务就应该初始化TestBed。

谢谢

2 个答案:

答案 0 :(得分:0)

我们的团队遇到了同样的问题。一种解决方案是将TestBed初始化提取到一个单独的文件中并保护它,以便它只被初始化一次:

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;
    }
}

然后您可以使用beforeAll块中的初始化程序来获取TestBed的实例:

import { TestBedInitializer } from './init';

describe('YourSystemUnderTest', () => {

    let TestBed;

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

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

    ...

});

此解决方案的优势在于您不依赖于以任何特定顺序运行的测试套件。这使您可以单独或一次性运行套件,而无需更改代码。

答案 1 :(得分:-1)

没有必要创建自己的MockHttp类,因为Angular已经创建了一个类:https://angular.io/docs/ts/latest/api/http/testing/index/MockBackend-class.html

示例用法是这样的:

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()代替inject()包装器。