TypeError xxx.subscribe不是函数

时间:2017-08-17 11:01:51

标签: angular typescript karma-jasmine

我正在编写一个基于Angular 4和Material 2的应用程序。它可以“实时”工作,但是当我决定编写一些单元测试时,我遇到了麻烦。

似乎我遇到系统错误导致以下错误消息:

  

TypeError:this.serviceXXX.getAll(...)。subscribe不是函数

这是我的服务代码

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

我已经找到并阅读了很多类似问题的问题,但没有一个解决方案适合我。

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

1 个答案:

答案 0 :(得分: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()方法。