2017-01-10 14 views
2

ジャスミンを使ってangle2アプリをテストしようとしましたが、サービスを注入しようとしたときに、スパイは注入されたコールでピックアップしません。angular2 /ジャスミン注入モックサービスがスパイを呼び出さない

テストスイート:

import { TestBed, inject, tick, fakeAsync, ComponentFixture } from '@angular/core/testing'; 
import { By } from '@angular/platform-browser'; 
import { RouterTestingModule } from '@angular/router/testing'; 

import { RoomComponent } from './room.component'; 

import { Room } from './room'; 
import { RoomService } from './room.service'; 
import { MockRoomService } from '../mock/mock.room.service'; 
import { BaseRequestOptions, Http, ConnectionBackend, Response, ResponseOptions } from '@angular/http'; 
import { MockBackend } from '@angular/http/testing'; 

... 

beforeEach(fakeAsync(() => { 
TestBed.configureTestingModule({ 
    declarations: [ 
    RoomComponent 
    ], 
    providers: [ 
    { 
     provide: Http, useFactory: (backend: ConnectionBackend, defaultOptions: BaseRequestOptions) => { 
     return new Http(backend, defaultOptions); 
     }, 
     deps: [MockBackend, BaseRequestOptions] 
    }, 
    RoomService, 
    {provide: MockBackend, useClass: MockBackend}, 
    {provide: BaseRequestOptions, useClass: BaseRequestOptions} 
    ], 
    imports: [ 
    RouterTestingModule 
    ] 
}) 
.overrideComponent(RoomComponent, { 
    set: { 
    providers: [{provide: RoomService, useClass: MockRoomService}] 
    } 
}) 

... 

it('should have rooms after getRooms', inject([RoomService], fakeAsync((mockRoomService: MockRoomService) => { 
    let spy = spyOn(mockRoomService, 'getRooms').and.callThrough(); 
    fixture.detectChanges(); 
    tick(); 
    expect(spy).toHaveBeenCalled(); //Does not return true 
    expect(component.rooms).toBeDefined(); 
}))); 

検査済み自身が彼らが(モックサービスとダイレクトコールを使用して)仕事スパイ、およびコンポーネントは、テストデータを返す、むしろ実際のものよりもモックサービスを呼び出すこと:

LOG: 'ngInitified' 
PhantomJS 2.1.1 (Windows 7 0.0.0): Executed 6 of 21 (skipped 3) SUCCESS (0 secs/1.156 secs) 
LOG: 'method reached' 
PhantomJS 2.1.1 (Windows 7 0.0.0): Executed 6 of 21 (skipped 3) SUCCESS (0 secs/1.156 secs) 
LOG: 'mock service reached' 
PhantomJS 2.1.1 (Windows 7 0.0.0): Executed 6 of 21 (skipped 3) SUCCESS (0 secs/1.156 secs) 
LOG: [Object{_id: '12', gitrepo: 'repository', channel: 'slack channel'}, Object{_id: '42', gitrepo: 'newrepo', channel: 'dev'}] 
PhantomJS 2.1.1 (Windows 7 0.0.0): Executed 6 of 21 (skipped 3) SUCCESS (0 secs/1.156 secs) 
PhantomJS 2.1.1 (Windows 7 0.0.0) Component: Room should have rooms after getRooms FAILED 
    Expected spy getRooms to have been called. 

MockRoomServiceをまっすぐに注入しようとしました。 mockオブジェクトではなく、RoomServiceオブジェクトにスパイを置こうとしました。スパイが呼び出されたということも返されません。

モックサービス:

import { Injectable } from '@angular/core'; 
import { Http } from '@angular/http'; 
import { Room } from '../room/room'; 

@Injectable() 
export class MockRoomService { 
    testData: Room[] = [{"_id":"12","gitrepo": "repository", "channel": "slack channel"}, {"_id":"42","gitrepo": "newrepo", "channel": "dev"}]; 

    constructor(http: Http) { } 

    getRooms(): Promise<Room[]> { 
     console.log("mock service reached"); 
     return new Promise((resolve, reject) => { 
      resolve(this.testData); 
     }); 
    } 

... 

実際のサービス:

import { Room } from './room'; 
import { Http, Headers, RequestOptions } from '@angular/http'; 

import 'rxjs/add/operator/toPromise'; 

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

@Injectable() 
export class RoomService { 
    constructor (private http: Http) {} 

    getRooms(): Promise<Room[]> { 
     console.log("real service reached"); 
     return this.http.get('api/rooms/get') 
     .toPromise() 
     .then(res => res.json() as Room[]); 
    } 

... 

コンポーネント:

import { Component, OnInit } from '@angular/core'; 
import { Router } from '@angular/router'; 

import { Room } from './room'; 
import { RoomService } from './room.service'; 

@Component({ 
    selector: 'app-room', 
    templateUrl: './room.component.html', 
    styleUrls: ['./room.component.css'], 
    providers: [RoomService] 
}) 
export class RoomComponent implements OnInit { 
    title = 'Repos and Channels'; 
    rooms: Room[] = []; 
    constructor(
    private roomService: RoomService, 
    private router: Router, 
    ) {} 

    ngOnInit() { 
    console.log("ngInitified"); 
    this.getRooms(); 
    } 

    getRooms() { 
    console.log("method reached!"); 
    this.roomService.getRooms() 
     .then(room => { this.rooms = room; 
     console.log(this.rooms); } 
    ); 
    } 

... 

ヘルプ?

答えて

5

RoomServiceプロバイダのインスタンスが間違っています。あなたのコンポーネント

に対応するクラスをテストする必要があるのに対し、

it('should have rooms after getRooms', inject([RoomService], fakeAsync((mockRoomService: MockRoomService) => { 
    let componentMockRoomService = fixture.debugElement.injector.get(RoomService); 
    console.log(mockRoomService instanceof RoomService);   // true 
    console.log(componentMockRoomService instanceof RoomService);// false 

mockRoomServiceがルートプロバイダからのインスタンスであるので、ここであなたのテストは

let componentMockRoomService = fixture.debugElement.injector.get(RoomService); 
let spy = spyOn(componentMockRoomService, 'getRooms').and.callThrough(); 

Plunker Example

です
関連する問題