2017-08-17 100 views
1

我正在编写一个基于Angular 4和Material 2的应用程序。它的工作原理是“现场”,但是当我决定编写一些单元测试时,我遇到了麻烦。TypeError xxx.subscribe不是函数

看来,我有导致以下错误信息系统错误:

TypeError: this.serviceXXX.getAll(...).subscribe is not a function

这是我的服务代码

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

@Injectable() 
export class CompanyService { 

    constructor(private http: Http) { } 


    getAll() { 
     return this.http.get('/api/companies', this.jwt()).map((response: Response) => response.json()); 
    } 


    private jwt() { 
     // create authorization header with jwt token 
     const currentUser = JSON.parse(localStorage.getItem('currentUser')); 
     if (currentUser && currentUser.token) { 
      const headers = new Headers({ 'Authorization': 'Bearer ' + currentUser.token }); 
      return new RequestOptions({ headers: headers }); 
     } 
    } 

} 

我的组件:

import { Component, OnInit } from '@angular/core'; 
import {MdDialog, MdDialogRef} from '@angular/material'; 
import {Company} from '../../../models/_models'; 
import {CompanyService} from '../../../services/_services' 
import {Db} from './data-source' 
import {Observable} from 'rxjs/Observable'; 
import {Subscription} from 'rxjs/Subscription'; 

import {CompanyDetailsComponent} from '../company-details/company-details.component'; 

@Component({ 
    selector: 'app-company', 
    templateUrl: './company-listing.component.html', 
    styleUrls: ['./company-listing.component.scss'] 
}) 
export class CompanyListingComponent implements OnInit { 

    errorMessage: string; 
    dataSource; 
    displayedColumns: string[] = [ 'name', 'btns' ]; 

    constructor(public service: CompanyService, public dialog: MdDialog) { } 

    ngOnInit() { 
    this.loadAll(); 
    } 

    onCreate() { 
    this.showDetail(new Company('name')); 
    } 

    onEditUser(user: Company) { 
    } 

    onRemove(item: Company) { 

    } 

    loadAll() { 
    this.service.getAll() 
      .subscribe(
       data => { 
        this.dataSource = new Db(data); 
       }, 
       err => { 
        this.errorMessage = err; 
       }); 
    } 

    showDetail(item: Company) { 
    this.dialog.open(CompanyDetailsComponent, { 
     disableClose: true, 
      data: { 
      item: Company 
     } 
    } 
    ).afterClosed().subscribe(
     result => {this.loadAll(); } 
    ) 
    } 


} 

和我的测试班:

import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 
import { CompanyListingComponent } from './company-listing.component'; 
import { RouterTestingModule } from '@angular/router/testing'; 
import { MaterialModule, MdTableModule } from '@angular/material' 
import { CdkTableModule} from '@angular/cdk'; 
import { CompanyService } from './../../../services/_services'; 
import {mock, } from 'ts-mockito'; 
import 'rxjs/Rx'; 

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

    beforeEach(async(() => { 
    const companyServiceMock: CompanyService = mock(CompanyService) 
    TestBed.configureTestingModule({ 
     imports: [MaterialModule, 
       RouterTestingModule, 
       MdTableModule, 
       CdkTableModule], 
     declarations: [ CompanyListingComponent ], 
     providers: [ {provide: CompanyService, useValue: companyServiceMock} ] 
    }) 
    .compileComponents(); 
    })); 

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

    it('should be created',() => { 
    expect(component).toBeTruthy(); 
    }); 
}); 

我发现并阅读了许多类似问题的问题,但没有解决方案适用于我。

任何人都可以看到我做错了什么。

+0

只在测试过程中给出错误或者正常运行时工作正常吗? –

+1

我不熟悉你正在使用的Mocking框架,但是在使用服务模拟器之前,你不需要为getAll()方法设置一个存根? –

+0

Dean对你+1:你正在使用一个模拟服务,但是当它的getAll()方法被调用时,你不会告诉它要返回什么。所以它最可能返回null或undefined或一个空对象。 –

回答

0

如文档中ts-mockito says,尝试捻熄GETALL方法在测试类:

beforeEach(async(() => { 
    const companyServiceMock: CompanyService = mock(CompanyService); 
    when(companyServiceMock.getAll()).thenReturn(Observable.of([])); 
    TestBed.configureTestingModule({ 
    imports: [MaterialModule, 
       RouterTestingModule, 
       MdTableModule, 
       CdkTableModule], 
    declarations: [ CompanyListingComponent ], 
    providers: [ {provide: CompanyService, useValue: companyServiceMock} ] 
    }) 
    .compileComponents(); 
})); 

我想是因为你的companyServiceMock没有使用磕碰定义getAll()方法出现错误。

+0

我认为你是正确的。我已经添加了这一行:when(companyServiceMock.getAll).thenReturn((=)=> Observable.of([])),现在我有这个错误消息:失败:无法读取undefined –

+0

@lg的属性'add'。 lindstrom这个'add'属性用在哪里?我似乎无法在您的代码中找到它 – samAlvin

+0

我不知道它在哪里使用,,,也许在ts-mockito ,,但我无法找到它.. –

相关问题