2017-06-18 108 views
1

我有一個簡單的服務如何測試可觀察的Angular 2?

import { Injectable } from '@angular/core'; 
import { Http } from '@angular/http'; 
import { Observable } from 'rxjs/Observable'; 
import 'rxjs/add/operator/map'; 

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

    getTestData(): Observable<[{}]> { 
     return this.http 
      .get('https://jsonplaceholder.typicode.com/posts/1') 
      .map(res => res.json()) 
    } 
} 

和一個簡單的組件

import { Component, OnInit} from '@angular/core'; 
import { TodoService } from './todo.service'; 

@Component({ 
    selector: 'todo-component', 
    templateUrl: './todo-component.html', 
    styleUrls: ['./todo.css'] 
}) 

export class TodoComponent implements OnInit { 
    testList: Object; 

    constructor(private todoService: TodoService) { } 

    ngOnInit() { 
     this.todoService 
      .getTestData() 
      .subscribe((testList) => { 
       this.testList = testList 
      }); 

    } 
} 

,我試圖測試這個

import { TestBed, async } from '@angular/core/testing'; 
import { FormsModule } from '@angular/forms'; 
import { HttpModule } from '@angular/http'; 
import { BrowserModule } from '@angular/platform-browser'; 
import { Observable } from 'rxjs/Observable'; 

import { TodoComponent } from '../todo.component'; 
import { TodoService } from '../../todo/todo.service'; 

let todoService, 
    fixture, 
    comp, 
    todoList = [], 
    TodoServiceStub = { 
    getTestData: function() { 
     return { 
      userId: 1, 
      id: 1, 
      title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit', 
      body: `quia et suscipit 
        suscipit recusandae consequuntur expedita et cum 
        reprehenderit molestiae ut ut quas totam 
        nostrum rerum est autem sunt rem eveniet architecto` 
     } 
    } 
}, 
testDataFromService = { "someKey": "some Val"}; 

describe('Todo Component',() => { 

    beforeEach(async(() => { 

     TestBed.configureTestingModule({ 
      declarations: [ TodoComponent ], 
      imports: [ 
       BrowserModule, 
       FormsModule, 
       HttpModule 
      ], 
      providers: [ 
       { 
        provide: TodoService, useValue: TodoServiceStub 
       }, 
      ], 
     }) 
     .compileComponents() 
     .then(() => { 
      fixture = TestBed.createComponent(TodoComponent); 
      comp = fixture.debugElement.componentInstance; 

     todoService = fixture.debugElement.injector.get(TodoService); 
      spyOn(todoService, 'getTestData').and.returnValue({ 
      subscribe:() => {} }); 
     }); 
    })); 

    it('should get data from the http call', async(() => { 
     comp.ngOnInit(); 

     expect(comp.testList).toBe(testDataFromService); 
    })) 
}); 

它得到:

Expected undefined to be Object({ someKey: 'some Val' }). 

嘗試遵循文檔,但comp.testList將不會被填充..如果我試圖調試這似乎是服務調用正在完成,但在測試中我無法達成解決價值..我在這裏做錯了什麼?

+1

您沒有正確嘲笑服務。 – Aravind

+0

@Aravind thnx!但我不這麼認爲,因爲當我向從localstorage獲取數據的服務中添加另一種方法時,我可以測試它!所以,服務注入罰款我猜.. 如果你的意思是嘲笑observable是不正確的,但我想聽聽如何。 – Mar

回答

3

您錯過了2件事。

  1. 你沒有正確地嘲笑你的服務。它應該返回Observable而不是原始數據。使用Observable.of來創建具有現有數據的觀察值。它也應該返回一個數組而不是一個單一的對象,因爲這是你在實際服務中定義的。如果您沒有使用過rxjs運算符的某種常規導入文件,請務必導入運算符Observable.of
  2. 在初始化之後,您必須讓Observable返回數據,然後才能檢查其在組件中的存在。爲此,請使用fakeAsynctick

更新代碼:

import { TestBed, async, tick, fakeAsync } from '@angular/core/testing'; 
import { FormsModule } from '@angular/forms'; 
import { HttpModule } from '@angular/http'; 
import { BrowserModule } from '@angular/platform-browser'; 

// if you have not already you should import the Observable.of operator for this test to work 
import { Observable } from 'rxjs/Observable'; 

import { TodoComponent } from '../todo.component'; 
import { TodoService } from '../../todo/todo.service'; 

let todoService, 
    fixture, 
    comp, 
    todoList = [], 
    TodoServiceStub = { 
    getTestData: function() { 
     // return an Observable like you do in your actual service and return an array 
     return Observable.of([{ 
      userId: 1, 
      id: 1, 
      title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit', 
      body: `quia et suscipit 
        suscipit recusandae consequuntur expedita et cum 
        reprehenderit molestiae ut ut quas totam 
        nostrum rerum est autem sunt rem eveniet architecto` 
     }]); 
    } 
}, 
testDataFromService = { "someKey": "some Val"}; 

describe('Todo Component',() => { 

    beforeEach(() => { 

     TestBed.configureTestingModule({ 
      declarations: [ TodoComponent ], 
      imports: [ 
       BrowserModule, 
       FormsModule, 
       HttpModule 
      ], 
      providers: [ 
       { 
        provide: TodoService, useValue: TodoServiceStub 
       }, 
      ], 
     }) 
     .compileComponents() 
     .then(() => { 
      fixture = TestBed.createComponent(TodoComponent); 
      comp = fixture.debugElement.componentInstance; 
    })); 

    it('should get data from the http call', fakeAsync(() => { 
     comp.ngOnInit(); 

     tick(); 

     expect(comp.testList).toBe(testDataFromService); 
    })) 
}); 
+1

'它應該返回一個Observable而不是原始數據'讓我明白它:) 所以我剛剛加入: spyOn(todoService,'getTestData')。and.returnValue(Observable.of(testDataFromService)); 它的工作原理!謝謝! – Mar