Angular Jasmine 测试用订阅填充数组

标签 angular asynchronous observable karma-jasmine

我正在尝试在简单的 Angular 应用程序中测试异步函数。

使用此组件:

组件

import { Component, OnInit } from '@angular/core';
import { DataService } from '../../services/data.service';
import { Component, OnInit } from '@angular/core';
import { DataService } from '../../services/data.service';

@Component({
  selector: 'app-post',
  templateUrl: './post.component.html',
  styleUrls: ['./post.component.css']
})
export class PostComponent implements OnInit {
  public posts:Post[];

  constructor(public data:DataService) { }

  ngOnInit() {
    this.data.getPosts().subscribe((res) => this.posts = res);
  }
}

export class Post{
  public userId:number;
  public id:number;
  public title:string;
  public body:string;
}

我可以通过数据服务层检索 json 帖子列表来填充帖子 PostComponent 类的属性。

服务

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

@Injectable()
export class DataService {

  constructor(public http: Http) { }

  getPosts() {
    return this.http.get('https://jsonplaceholder.typicode.com/posts').map(res => res.json());
  }
}

所以我在 suggestion 之后编写了这个 Jasmine 测试:

import { async, ComponentFixture, TestBed, fakeAsync } from '@angular/core/testing';
import { HttpModule } from '@angular/http';
import { DataService } from '../../services/data.service';
import { PostComponent } from './post.component';
import {Post} from '../post/post.component';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';

describe('PostComponent', () => {
  let component: PostComponent;
  let fixture: ComponentFixture<PostComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        HttpModule
      ],
      declarations: [PostComponent],
      providers: [DataService]
    })
      .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(PostComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('sholud call ngOnInit and fill Posts[]', async(() => {
    const foo:Post[] = [];

    const spy = spyOn(component, 'ngOnInit').and.returnValue(Observable.of(component.posts));
    component.ngOnInit();
    fixture.detectChanges();

    expect(component.posts.length).toBeGreaterThan(1);
  }));
});

但我收到此错误:

Failed: Cannot read property 'length' of undefined

TypeError: Cannot read property 'length' of undefined

如何测试它?

最佳答案

使用此解决:

it('should call ngOnInit and fill Posts[]', () => {
    spyOn(component, "ngOnInit").and.callThrough();
    component.ngOnInit();
    fixture.detectChanges();

    fixture.whenStable().then(() => {
      expect(component.posts.length).toBeGreaterThan(0);
    });
 });

关于Angular Jasmine 测试用订阅填充数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50135185/

相关文章:

c# - 使 Controller 方法异步还是保持同步?

javascript - MSCRM async javascript SDK.REST.retrieveMultipleRecords 仅返回 50 条记录,一次需要所有记录

c# - ASP.NET 异步标签更新

rxjs - 需要帮助将 rxjs forkjoin 调用转换为异步调用(在 ngrx @Effect 内)

Angular 7 - 我是否创建了太多订阅?

angular - 组件上不存在属性

angular - Ionic 2 - 禁用特定 View 的后退按钮

javascript - 如何获取 knockoutjs 可观察数组的下一个元素?

java - RxJava2 observable take 抛出 UndeliverableException

angular - 以 Angular 上传文件的补丁值