2017-02-12 5 views
5

간단한 테스트 예를 통해이 테스트 유틸리티 TestBed을 각도 -2로 배워보고 첫 번째 블로커에 충돌했습니다.테스트 베드가있는 angular2 테스트 구성 요소에 오류가 있습니다.

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'); 
    }); 
}); 
- 아래의 사양을

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

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

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

다음 - 구글이나 SO 검색이 일치하는 예를 양보하지 않았다, 그래서

, 나는 다음과 같이 매우 기본적인 구성 요소 header

카르마 테스트를 실행 중 - Error: No provider for String! in karma.entry.js

karma.entry.js은 기본적으로 그냥 생성자에서 매개 변수를 제거하면 아래에있는 내 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; 

입니다, 내 사양 폴더에 각각의 테스트를 통해 이동 한 후 테스트 베드에 대한 테스트 ENV 구성을 설정하고있다 구성 요소 클래스의 테스트가 성공하므로 일부 사전 구성이 누락되어 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

모듈 공급 업체

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

구성 요소의 분사 토큰보다에

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

구성 토큰을 사용한다 : 원시 주입의 올바른 사용을의

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

. 여기

자세한 내용 : https://angular.io/docs/ts/latest/guide/dependency-injection.html#!#opaquetoken

추신 :

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

을 그리고 테스트 구성 요소를 만드는 것보다 및 'test'title을 기대하십시오 TITLE_TOKEN이 테스트 모듈에 추가해야합니다 구성 요소를 테스트합니다.

+0

ok 그래서 TestBed가 컴포넌트 클래스를 인스턴스화하는 데 사용하는 각도 DI 프레임 워크로, 원시 타입이나 인터페이스를 컴포넌트의 생성자에 직접 삽입 할 수 없으며 'OpaqueToken' 래퍼가 필요합니다. 이전에 DI를 읽었을 때 나는이 부분을 게으름에서 그냥 건너 뛰었습니다. :) 이것이 문제였습니다. Thnx @mrkosima, 저는이 DI 패턴이 의미가 있다고 생각합니다. 왜냐하면 Typescript를 사용하면 대부분 OOPS 패턴을 사용하고 클래스 유형이나 각도 서비스를 구성 요소 생성자에게 전달할 것이기 때문입니다. 다시 감사드립니다. – kkap