Angular2:无法使用TestBed.compileComponent()使用templateUrl测试组件

时间:2016-10-03 15:57:44

标签: unit-testing angular karma-jasmine

我正在尝试获取Angular2测试API和TestBed.compileComponents()的基础知识让我疯狂。要么像我这样称呼它:

beforeEach( done => {
  TestBed.configureTestingModule({
    declarations: [MyComponent]
  })
  .compileComponents().then( () => {
    fixture = TestBed.createComponent(MyComponent);
    component = fixture.componentInstance();
  });
  done();
});

然后我的组件在我的测试中未定义(我相信,因为compileComponent是异步的,测试是在我的var组件获取值之前运行的)

要么那样(如documentation中所述):

beforeEach( async(() => {
  TestBed.configureTestingModule({
    declarations: [MyComponent]
  }))
  .compileComponents();

beforeEach( () => {
  fixture = TestBed.createComponent(HomeComponent);
  component = fixture.componentInstance();
});

然后我收到错误:This test module uses the component HomeComponent which is using a "templateUrl", but they were never compiled. Please call "TestBed.compileComponents" before your test.

有人可以提供帮助吗?

忘了说我使用webpack和RC6

5 个答案:

答案 0 :(得分:3)

试试这个:

beforeEach( async( () => {
  TestBed.configureTestingModule({
    declarations: [MyComponent]
  })
  .compileComponents().then( () => {
    fixture = TestBed.createComponent(HomeComponent);
    component = fixture.componentInstance();
  });
}));

答案 1 :(得分:2)

试试这个:

describe('FooComponent', function () {
    let fixture: ComponentFixture<FooComponent>;

    beforeEach(() => {
        TestBed.configureTestingModule({
            declarations: [FooComponent]
        });

        fixture = TestBed.createComponent(FooComponent);
        fixture.detectChanges();
    });

这里你不需要异步性。

答案 2 :(得分:1)

我在测试组件已经将测试移动到另一个文件夹时显然遇到了同样的问题,这就是我设法测试组件的方法。

这是一个有效的示例,有一个名为&#34; isLoggedIn&#34;的布尔值。在我的组件中,如果用户登录,我就会知道

import { async, TestBed } from '@angular/core/testing';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
import { MyComponent } from './MyComponent';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { UserService } from '../../app/shared/services/userService';



describe('ContentComponentTest', () => {

    // Instance of data-model.spec
    let dataModel = new DataModels();

    let userServiceStub: any = {
        getUserCookie() {
            return 'John';
        }
    };

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

    beforeEach(() => {
        TestBed.configureTestingModule({
            declarations: [MyComponent],
            providers: [
                { provide: UserService, useValue: userServiceStub }],
            schemas: [NO_ERRORS_SCHEMA]
        });
    });

    it('Test if user isLoggedIn', async(() => {
        // Overrides here, if you need them
        TestBed.overrideComponent(MyComponent, {
            set: {
                template: '<div>Overridden template here</div>'
                // ...
            }
        });

        TestBed.compileComponents().then(() => {
            const fixture = TestBed.createComponent(MyComponent);

            // Access the dependency injected component instance
            const app = fixture.componentInstance;

            expect(app.isLoggedIn).toBe(false);

            // Detect changes as necessary
            app.ngOnInit();
            fixture.detectChanges();

            expect(app.isLoggedIn).toBe(true);
        });
    }));

});

但是对于注入特定组件的提供程序,您必须模拟它们。例如:

providers:    [ {provide: UserService, useValue: userServiceStub } ]

答案 3 :(得分:0)

我遇到了同样的问题。我认为问题出在组件模板中。如果您使用其他一些自定义组件,但未在测试模块中指定它们,则Angular会抛出该错误(当然非常误导)。

那么,你接下来的选择:

  1. 在TestBed配置中指定所有已使用的组件
    1. 作为其变体,您可以通过相应的模拟来存储所有组件。
  2. 使用NO_ERRORS_SCHEMA进行浅层测试,如https://angular.io/docs/ts/latest/guide/testing.html#shallow-component-test
  3. 所述

答案 4 :(得分:0)

为了建立Zonkil的答案,我发现要让它工作,我必须实际设置夹具并在测试中创建组件。例如:

it('test the component renders',() => {      
        fixture = TestBed.createComponent(AppComponent);
        comp = fixture.componentInstance; 
        fixture.detectChanges();
        expect(comp).toBeDefined();
    });