简体   繁体   English

如何测试可观察的Angular 2?

[英]How to test observable Angular 2?

I have a simple service 我有一个简单的服务

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())
    }
}

and a simple component 和一个简单的组件

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
            });

    }
}

and I am trying to test this 而我正试图测试这个

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);
    }))
});

It gets: 它得到:

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

Tried to follow the docs but the comp.testList will be not filled.. If I try to debug this it seems like the service call is being done but in test I can't reach to resolve value.. What am I doing wrong here? 试图遵循文档,但comp.testList将不会被填充..如果我尝试调试这似乎服务调用正在完成但在测试我无法达到解决价值..我在这里做错了什么?

You are missing 2 things. 你缺少两件事。

  1. you didn't mock your service correctly. 你没有正确地模仿你的服务。 It should return an Observable and not raw data. 它应该返回一个Observable而不是原始数据。 Use Observable.of to create an observable with existing data. 使用Observable.of创建包含现有数据的observable。 It also should return an array and not a single object as that is what you defined in your actual service. 它也应该返回一个数组而不是单个对象,因为这是您在实际服务中定义的。 Be sure to import the operator Observable.of if you do not have some sort of general import file for used rxjs operators. 如果您没有使用某些rxjs运算符的常规导入文件,请务必导入运算符Observable.of
  2. After init you have to let the Observable return the data before you can check for its presence in the component. 在init之后,您必须让Observable返回数据,然后才能检查它在组件中的存在。 Use fakeAsync and tick for this. 使用fakeAsynctick

Updated code: 更新的代码:

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);
    }))
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM