2016-10-28 83 views
5

我想測試一個具有所有unsubscribe()方法調用的ngOnDestroy()方法的組件。但是,在測試時,當我運行我的測試文件(SPEC文件),它給了我錯誤說:無法讀取屬性取消訂閱undefined:Angular2測試

import { Subscription } from 'rxjs/Subscription'; 

所以我覺得這個:

cannot read property 'unsubscribe' of undefined 

我已經在我的測試文件中做了以下進口應該足以獲得Subscription中的所有方法,但仍然存在錯誤。另外,我嘗試在我的'imports','declarations'和'providers'列表中添加'Subscription',但錯誤仍然存​​在。

下面的代碼片段:

//component 
import { Component, OnInit, OnDestroy } from '@angular/core'; 
import { Subscription } from 'rxjs/Subscription'; 
import { 
NinjaService } from '../../../../ninja.service'; 


@Component({ 
selector: 'ninja-files', 
templateUrl: './ninja-files.component.html', 
styleUrls: ['./ninja-files.component.css'] 
}) 
export class ninjaFilesComponent implements OnInit, OnDestroy { 

showNinjaFiles: boolean = true; 

addFileSubscription: Subscription; 

constructor(private ninjaService: NinjaService) { 
........ 
} 

ngOnInit() { 
    this.addFileSubscription = this.NinjaService.AddedFile$ 
    .subscribe((fileFormat: FileFormat) => { 
    console.log('File being added: ' + fileFormat.fileName); } 

    ngOnDestroy() { 
    this.addFileSubscription.unsubscribe(); 
} 
} 

然後,我有此組件的測試文件,如下所示:

import { Component, OnInit, OnDestroy } from '@angular/core'; 
import { Subscription } from 'rxjs/Subscription'; 
import { 
NinjaService } from '../../../../ninja.service'; 
import { TestBed, async, fakeAsync ,ComponentFixture, } from '@angular/core/testing'; 
import { DebugElement } from '@angular/core'; 
import { By }    from '@angular/platform-browser'; 
import {} from 'jasmine'; 

describe('Component: NinjaFiles',() => { 

    let fixture: ComponentFixture<ninjaFilesComponent>; 
    let component: ninjaFilesComponent; 
    let ninjaServiceStub; 

beforeEach(async(() => { 
//stub NinjaService 
let ninjaServiceStub= {}; 

fixture = TestBed.configureTestingModule({ 
declarations: [ ninjaFilesComponent], 
}).createComponent(ninjaFilesComponent); 
component = fixture.componentInstance; 

})); 

it('Page Title', async(() => { 
let pageTitle = fixture.debugElement.query(By.css('.page-title')); 
expect(pageTitle).toBeTruthy(); 
})); 

it('Counting the files',() => { 
    let fileCount= fixture.debugElement.query(By.css('.file-count')); 
    expect(fileCount).toBeTruthy(); 
}); 

當我運行上面的測試代碼,它給了我錯誤說「無法讀取未定義屬性'取消訂閱'(這意味着它無法定義我在組件類中定義的訂閱對象'addFileSubscription')。

Can有人建議一種解決方法?

+1

嘗試調用'fixture.detectChanges();'在'beforeEach()'末尾或在開始的測試中調用。 –

+0

試過了,沒有幫助! :( – Aiguo

+0

您能否驗證'ngOnInit()'被調用? –

回答

8
import { Subscription } from 'rxjs/Subscription'; 

所有這一切都意味着,您可以從ninjaFilesComponent類文件訪問Subscription類。

問題是addFileSubscription從不初始化。爲了使ngOnInit被調用,您需要從調用

fixture.detectChanges(); 

除此之外,我看到其他的問題是:

  1. 你從來沒有存根添加到供應商

    TestBed.configureTestingModule({ 
        providers: [ 
        { provide: NinjaService, useValue: ninjaServiceStub } 
        ] 
    }) 
    
  2. 您需要在存根中實際執行某些操作

    let ninjaServiceStub = { 
        AddedFile$: Observable.of(new FileFormat(...)) 
    } 
    
  3. 你不是在零件以服務正確

    this.NinjaService.AddedFile$ 
    // should be 
    this.ninjaService.AddedFile$ 
    // lowercase 
    
+0

感謝您的建議@peeskillet!還有一個問題,'FileFormat'在這裏是一個接口,所以我不能使用像'AddedFile $:Observable.of (新的FileFormat(...))'在我的ninjaServiceStub。你有建議如何創建一個接口的observable? – Aiguo

+0

你不需要使用這個類。無論接口的結構是什麼,只要使用一個對象字面值,就像'{whatever:'properties',它:'has'}' –

+0

[閱讀](http://www.typescriptlang.org/docs/handbook/type -compatibility.html)以更好地瞭解打字稿類型的工作方式 –

1

添加fixture.detectChanges();我的測試解決這個問題跑採用了棱角分明2 CLI與材料設計測試時,我正面臨着。

感謝您的解決方法!