单元测试 – 角度2使用forkJoin测试组件

我的应用程序中有一个LogComponent.在ngOnInit中我通过LogService从服务器检索日志并将其显示在网格中.

以下是2种方法

第一名:

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

import { Log } from './log';
import { LogService } from './log.service';
import * as globals from '../../globals';
import { DataTransformService,HttpHandlerService,StateManagerService } from '../../shared';

@Component({
  selector: 'app-log',templateUrl: 'log.component.html',styleUrls: ['log.component.css'],providers: [ DataTransformService,LogService,StateManagerService]
})
export class LogComponent implements OnInit {

  localGlobals: any = globals;

  logs: Log[];

  currentPage: number;
  totalRecords: number = 0;
  firstRowIndex: number = 0;

  constructor(
    private stateManagerService: StateManagerService,private httpHandlerService: HttpHandlerService,private logService: LogService,private dataTransformService: DataTransformService,private router: Router
  ) {}

  ngOnInit() {

    //get page number from local storage
    this.currentPage = this.stateManagerService.getParamFromState(this.router.url,'page');
    this.firstRowIndex = this.currentPage * this.localGlobals.ROWS_PER_PAGE - this.localGlobals.ROWS_PER_PAGE;

    //get total count 
    let respHandler = (res: any) => {
      this.totalRecords = res.headers.get('X-Pagination-Total-Count');
      return this.httpHandlerService.extractData(res);
    };

    this.logService.search(this.currentPage,respHandler).subscribe(
      logs => {
        this.logs = logs;
      },err => console.error(err) 
    );

  }

}

第一种方法使用此函数来检索日志:

this.logService.search(this.currentPage,respHandler).subscribe(
  logs => {
    this.logs = logs;
  },err => console.error(err) 
);

检索日志的第二种方法是通过Observable.forkJoin:

import { Component,'page');
    this.firstRowIndex = this.currentPage * this.localGlobals.ROWS_PER_PAGE - this.localGlobals.ROWS_PER_PAGE;

    //get total count 
    let respHandler = (res: any) => {
      this.totalRecords = res.headers.get('X-Pagination-Total-Count');
      return this.httpHandlerService.extractData(res);
    };

    Observable.forkJoin(
        this.logService.search(this.currentPage,respHandler)
    ).subscribe(
      data => {
        this.logs = data[0];
      },err => console.error(err) 
    );

  } 

}

第二种方法使用此函数来检索日志:

Observable.forkJoin(
        this.logService.search(this.currentPage,err => console.error(err) 
    );

我对此组件进行了测试,检查在init之后初始化属性

import { DebugElement,NO_ERRORS_SCHEMA }    from '@angular/core';
import { async,ComponentFixture,Testbed } from '@angular/core/testing';
import { FormsModule } from '@angular/forms';
import { By } from '@angular/platform-browser';
import { Router } from '@angular/router';
import { ReplaySubject } from 'rxjs/Rx';

import { Log } from './log';
import { LogComponent } from './log.component';
import { LogService } from './log.service';
import { DataTransformService,LocalStorageService,StateManagerService } from '../../shared';

let comp:    LogComponent;
let fixture: ComponentFixture<LogComponent>;
let de:      DebugElement;

describe('LogComponent',() => {

  // async compile html and css
  beforeEach(async(() => {

    let project = new ReplaySubject(1);
    let logServiceStub = {
        search: (pageNum: number,respHandler: any) => {
            let logs = [
                { id: 1,ip: '127.0.0.1',user_id: 1,notification_event_id: 1,created_at: 1 },{ id: 2,ip: '127.0.0.2',user_id: 2,notification_event_id: 2,created_at: 2 }
            ];
            project.next(logs);
            return project;
        }
    };

    let routerStub = {
        url: 'log_url'
    };

    Testbed.configureTestingModule({
        declarations: [ LogComponent ],imports: [ FormsModule ],providers: [
            DataTransformService,{ provide: Router,useValue: routerStub },StateManagerService
        ],schemas: [ NO_ERRORS_SCHEMA ]
    })
    .overrideComponent(LogComponent,{
      set: {
        providers: [
          { provide: LogService,useValue: logServiceStub }
        ]
      }
    })
    .compileComponents();

  }));

  // synchronous 
  beforeEach(() => {

    fixture = Testbed.createComponent(LogComponent);

    // LogComponent test instance
    comp = fixture.componentInstance;

    de = fixture.debugElement;

  });

  it('initial variables are set after init',() => {

      fixture.detectChanges(); 

      console.log(comp.logs);

      //Todo: test not working when requests are in forkJoin
      expect(comp.currentPage).toBe(1);
      expect(comp.firstRowIndex).toBe(0);
      expect(comp.logs).not.toBeUndefined();
      expect(comp.logs.length).toBe(2);

  });

});

问题:当我使用第一种方法(没有Observable.forkJoin)运行测试时,它工作正常.但是当我使用第二种方法(使用Observable.forkJoin)运行测试时,它失败并显示错误

Expected undefined not to be undefined.

所以在fixture.detectChanges()之后没有初始化日志.看起来如果请求在Observable.forkJoin()中,则初始化不会运行.我知道Observable.forkJoin()中只有一个请求,我可以使用第一种方法,但我在系统中有其他组件使用多个请求,所以我需要解决这个问题.

希望你明白我的意思.

提前致谢.

好吧,经过一番挣扎,我发现需要完成可观察的forkJoin来捕获它.
所以,如果你打电话
project.next(东西)
这不够.
你还需要打电话:
project.complete()
让它工作!

请记住,您始终可以使用zip而不是forkJoin来处理.next传播以及.complete

相关文章

ANGULAR.JS:NG-SELECTANDNG-OPTIONSPS:其实看英文文档比看中...
AngularJS中使用Chart.js制折线图与饼图实例  Chart.js 是...
IE浏览器兼容性后续前言 继续尝试解决IE浏览器兼容性问题,...
Angular实现下拉菜单多选写这篇文章时,引用文章地址如下:h...
在AngularJS应用中集成科大讯飞语音输入功能前言 根据项目...
Angular数据更新不及时问题探讨前言 在修复控制角标正确变...