2017-02-12 14 views
5

пытается узнать эту утилиту тестирования TestBed в угловом-2 с простым примером и ударил мой первый блокиратор. Google или SO поиск не дает никакого совпадения примера,ошибка с компонентом с угловым тестированием с тестовым стендом

так, у меня есть очень основной компонент header, как показано ниже -

import { Component } from '@angular/core'; 

@Component({ 
    selector: 'header', 
    template: '' 
}) 
export class HeaderComponent{ 
    public title: string; 

    constructor(testparam: string){ 
     this.title = 'test'; 
    } 
} 

и затем его спецификация, как показано ниже -

import { TestBed } from '@angular/core/testing'; 
import { HeaderComponent } from './header.component'; 

describe('HeaderComponent Test',() => { 
    let component: HeaderComponent; 

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

     const fixture = TestBed.createComponent(HeaderComponent); 
     component = fixture.componentInstance; 
    }); 

    it('should have the component defined',() => { 
     expect(component).toBeDefined(); 
    }); 

    it('should initialize the title to test',() => { 
     expect(component.title).toBe('test'); 
    }); 
}); 

выполнения теста карма бросает - Error: No provider for String! in karma.entry.js

karma.entry.js в основном только настройка конфигурации теста окр для Testbed, а затем проходит через каждый тест в моей папке спецификации, ниже мой karma.entry.js

require('core-js/es6'); 
require('core-js/es7/reflect'); 

require('es6-shim'); 
require('reflect-metadata'); 
require('zone.js/dist/zone'); 
require('zone.js/dist/long-stack-trace-zone'); 
require('zone.js/dist/proxy'); 
require('zone.js/dist/sync-test'); 
require('zone.js/dist/jasmine-patch'); 
require('zone.js/dist/async-test'); 
require('zone.js/dist/fake-async-test'); 
require('rxjs/Rx'); 

const browserTesting = require('@angular/platform-browser-dynamic/testing'); 
const coreTesting = require('@angular/core/testing'); 

coreTesting.TestBed.initTestEnvironment(
    browserTesting.BrowserDynamicTestingModule, 
    browserTesting.platformBrowserDynamicTesting() 
); 

const context = require.context('../src', true, /\.spec\.ts$/); 

context.keys().forEach(context); 

Error.stackTraceLimit = Infinity; 
jasmine.DEFAULT_TIMEOUT_INTERVAL = 2000; 

Если удалить параметр из конструктора класса компонента, тесты проходят, поэтому я думаю, что мне не хватает некоторой предварительной конфигурации, что приводит к тому, что TestBed.createComponent(HeaderComponent) не будет правильно компилировать конструктор компонента с параметром типа строки.

любая подсказка, что мне может не хватать?


UPDATE:

, если это поможет кому - на основе ответа @ mrkosima, мой обновленный класс компонент теперь выглядит, как показано ниже, и блок тестирует все проходят теперь хорошо :)

import { Component, OpaqueToken, Inject } from '@angular/core'; 

export let TITLE_TOKEN = new OpaqueToken('title token'); 

@Component({ 
    selector: 'header', 
    template: '', 
    providers: [{ provide: TITLE_TOKEN, useValue: 'test' }] 
}) 
export class HeaderComponent{ 
    public title: string; 

    constructor(@Inject(TITLE_TOKEN) titleParam: string){ 
     this.title = titleParam; 
    } 
} 

ответ

4

Вы правы, что основная причина проблемы в аргументе конструктора.

Во время создания компонента Injector пытается решить все зависимости, указанные в конструкторе. Injector ищет зависимости по типам поставщиков. Подробнее о DI здесь: https://angular.io/docs/ts/latest/guide/dependency-injection.html

Это означает, что если компонент имеет constructor(authService: AuthService) { }, то Injector ищет AuthService токена поставщиков.

То же самое в вашем случае - ваш компонент зависит от String. Но нет ни одного провайдера с маркером String.

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

Вместо этого OpaqueToken следует использовать

export let TITLE_TOKEN = new OpaqueToken('title token'); 

Настройка маркера в поставщиках модуля

providers: [{ provide: TITLE_TOKEN, useValue: 'title value' }] 

Than нагнетающих маркеров в компоненте:

constructor(@Inject(TITLE_TOKEN) title: string) { 
    this.title = title; 
} 

Это правильное использование инъекционного примитива ,

Подробнее здесь: https://angular.io/docs/ts/latest/guide/dependency-injection.html#!#opaquetoken

PS: чтобы проверить вашу КОМПОНЕНТ TITLE_TOKEN должен быть добавлен модуль тестирования:

import {TITLE_TOKEN} from ... 
TestBed.configureTestingModule({ 
     providers: [ { provide: TITLE_TOKEN, useValue: 'test' } ] 
}); 

И чем создать тестовый компонент и ожидать title как 'test'.

+0

ОК, поэтому его угловая рамка DI, используемая TestBed для создания экземпляра класса компонента, из-за которого невозможно вводить примитивные типы или интерфейсы, сортировать вещи непосредственно в конструкторе компонента и требует оболочки «OpaqueToken». Раньше, когда я читал DI, я пропустил эту часть только из лени :) и это было проблемой. Thnx @mrkosima, я думаю, что этот шаблон DI имеет смысл, потому что теперь с помощью TypScript мы в основном будем использовать шаблоны OOPS и в основном будем передавать типы классов или угловые службы конструкторам компонентов, еще раз спасибо. – kkap

 Смежные вопросы

  • Нет связанных вопросов^_^