2016-08-12 6 views
7

別のサービスを使用するコンポーネントをテストしようとしています。そして私はサービスのモックを提供することによってコンポーネントを分離したいと思っています。 RC5の前に私は単純にaddprovidersを使うことができます。これは廃止され、次のRCで削除されます。代わりにTestBedを使用する必要があります。私が何らかの理由でモック角を提供すると、モックが依存するサービスを探し続ける。 DI exceptionを投げます。すべての依存関係を提供するとテストは機能しますが、テストスイートごとに自分自身を繰り返す必要はありません。そして、これは基本的なオブジェクト指向の原則を破ります。 私のテストスイート:モック付き角2 TestBed

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

    class DummyRestApiTestService { 

    GetAll() { 

     return Rx.Observable.create(observer => { 

     let data:Data[] = []; 

     data.push({ 
      id: 0, 
      data: 'data' 
     }); 

     observer.next(data); 
     observer.complete(); 

     }); 
    } 

    Add(data) { 
    } 
    } 
    let fixture; 
    let myMockWindow:Window; 
    // ToDo use the mocks 
    beforeEach(() => { 
    myMockWindow = <any> {location: <any> {hostname: '127.0.0.1'}}; 
    TestBed.configureTestingModule({ 
     declarations: [DummyRestApiComponent], 
     providers: [ 
     // ServerAddressResolverService, 
     DummyRestApiComponent, 
     // ConfigurationService, 
     {provide: DummyRestApiService, useClass: DummyRestApiTestService}, 
     // {provide: Window, useValue: myMockWindow} 
     ], 
     imports: [FormsModule, HttpModule] 
    }); 
    TestBed.compileComponents().catch(error => console.error(error)); 


    // addProviders([ 
    // DummyRestApiComponent, 
    // {provide: DummyRestApiService, useClass: DummyRestApiTestService}, 
    // ]); 
    }); 


    describe('Initializing',() => { 

    beforeEach(async(() => { 
     console.log('Compiling'); 
     TestBed.compileComponents().catch(error => console.error(error)); 
     console.log('Compiling again'); 
    })); 

    it('should create an instance', async(() => { 
     var fixture = TestBed.createComponent(DummyRestApiComponent); 
     fixture.detectChanges(); 
     expect(fixture.debugElement.componentInstance).toBeTruthy(); 
     } 
    )); 

}); 

角度2.0.0-RC5私はちょうどRC5に私のシードプロジェクトを更新しました

+0

を私はこれを確認しました。あたかも黙っていないかのように、サービスのインポートを指定する必要があります。少なくともRC5では。しかし、テストではモックサービスを使用します。 – Dave

答えて

2

とシンプルなTODOコンポーネントのための私のテストスイートは、次のようになります。

import { provide } from '@angular/core'; 
import { TestBed, ComponentFixture, async } from '@angular/core/testing'; 
import { Observable } from 'rxjs/Observable'; 
import 'rxjs/add/observable/of'; 

import { TodoModule } from './todo.module'; 
import { TodoComponent } from './todo.component'; 
import { Todo, TodoService } from './todo.service'; 

class MockTodoService { 
    get todos$(): Observable<Todo[]> { 
     return Observable.of<Todo[]>([ 
      { task: 'Task 1', description: 'Description 1', completed: false }, 
      { task: 'Task 2', description: 'Description 2', completed: false } 
     ]); 
    } 

    loadAll() { } 

    add(newTodo: Todo) { } 
} 

describe('TodoComponent',() => { 

    beforeEach(() => { 
     this.service = new MockTodoService(); 

     TestBed.configureTestingModule({ 
      imports: [TodoModule], 
      providers: [provide(TodoService, { useValue: this.service })] 
     }); 

     this.fixture = TestBed.createComponent(TodoComponent); 
    }); 

    it('should print out todo tasks', async(() => { 
     this.fixture.whenStable().then(() => { 
      let element = this.fixture.nativeElement; 
      this.fixture.detectChanges(); 

      expect(element.querySelectorAll('li').length).toBe(2); 
     }); 
    })); 

    it('should call the service on init', async(() => { 
     this.fixture.whenStable().then(() => { 
      spyOn(this.service, 'loadAll'); 
      this.fixture.detectChanges(); 

      expect(this.service.loadAll).toHaveBeenCalled(); 
     }); 
    })); 
}); 

シードプロジェクトそのものはhttps://github.com/froko/ng2-seed-webpack

で見つけることができます。

+2

[RC5変更ログ](https://github.com/angular/angular/blob/master/CHANGELOG.md#breaking-changes-1)には、「ngModel」が更新時に常に非同期であることも記載されています。テストでは、 'ComponentFixture.detectChanges'を呼び出す代わりに、非同期の' ComponentFixture.whenStable'を使う必要があります。既に 'whenStable'を使用していますが、' detectChanges'も使用しています。 'this.fixture.detectChanges()'を今すぐ削除すれば、あなたのテストは動作する可能性はありますか? –

5

パトリック・イネイケンズは答えの使用を推奨していますが、これは非推奨です。

providers: [provide(TodoService, { useValue: this.service })] 

が代わりに読んでください:

providers: [{provide:TodoService, useValue: this.service }] 
関連する問題