Angular2: Невозможно протестировать компонент с templateUrl с помощью TestBed.compileComponent()

Я пытаюсь понять основы тестового API Angular2, и TestBed.compileComponents() сводит меня с ума. Либо я называю это так:

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

И тогда мой компонент не определен в моем тесте (я полагаю, поскольку compileComponent является асинхронным, тест запускается до того, как мой компонент var получает значение)

Либо так (как описано в документации):

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 ответов

Решение

Попробуй это:

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

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

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

Вам не нужна асинхронность здесь.

Попробуй это:

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

Я столкнулся с той же проблемой, по-видимому, при тестировании компонентов, переместив тест в другую папку, и именно так мне удалось протестировать компонент.

Вот пример, который работает, в моем компоненте есть логическое значение isLoggedIn, которое я проверяю, если пользователь вошел в систему

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

Просто, чтобы получить ответ от Zonkil, который я нашел, чтобы заставить это работать, мне нужно было на самом деле установить прибор и создать компонент в тесте. Например:

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

Я столкнулся с той же проблемой. Я думаю, что проблема в вашем компоненте шаблона. Если вы используете некоторые другие пользовательские компоненты, но не указали их в модуле тестирования, то Angular выдает эту ошибку (конечно, очень вводящая в заблуждение).

Итак, вам доступны следующие варианты:

  1. Укажите все используемые компоненты в конфигурации TestBed
    1. Как вариант, вы можете заглушить все компоненты с помощью соответствующих макетов.
  2. используйте NO_ERRORS_SCHEMA для поверхностного тестирования, как описано здесь https://angular.io/docs/ts/latest/guide/testing.html
Другие вопросы по тегам