如何修复“ TypeError:this.productService.getProducts不是函数”错误?

时间:2019-05-06 08:27:33

标签: angular typescript testing mocking

我正在使用最新版本的angular,并试图编写单元测试来测试Service,该服务从Angular中的Web API获取产品列表,并且对此是新手。 我能够在页面上显示产品,因此get方法似乎可以工作,但无法解决测试错误。有什么帮助吗?

在可视代码终端中运行ng测试时,测试失败:“应通过Get从API检索产品” 出现错误:

  

应通过Get

从API检索产品
TypeError: mockService.getProducts is not a function
    at UserContext.<anonymous> (http://localhost:9876/_karma_webpack_/webpack:/src/app/services/product.service.spec.ts:45:19)
    at ZoneDelegate../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:391:1)
    at ProxyZoneSpec.push../node_modules/zone.js/dist/zone-testing.js.ProxyZoneSpec.onInvoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-testing.js:289:1)
    at ZoneDelegate../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:390:1)
    at Zone../node_modules/zone.js/dist/zone.js.Zone.run (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:150:1)

app.component.ts

import { Component,OnInit } from '@angular/core';
import { ProductService } from './services/product.service';
import { Product } from './models/product.model';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})  
export class AppComponent implements OnInit{

  title = 'Products App';
  products : Product[];

  constructor(private productService:ProductService)
  {
     console.log('constructor ran');
  }

  ngOnInit()
  {
    console.log('ngOnInit ran...');
    this.productService.getProducts().subscribe(products=> {
      console.log(products);
      this.products = products.map(x => new Product(x));
    })
  }
}

product.service.ts

import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { map } from  'rxjs/operators'
import { Product } from './../models/product.model';

@Injectable({
  providedIn: 'root'
})
export class ProductService {

  constructor(private http:Http) { 
    console.log('Product Service connected...');    
  }

  getProducts(){
      return this.http.get('http://localhost:50324/v1/products')
      .pipe(map(res=> res.json()));
  }  
}

product.service.spec.ts

import { TestBed } from '@angular/core/testing';
import { MockBackend } from '@angular/http/testing';
// import { HttpClient } from '@angular/common/http';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';

import { ProductService } from './product.service';
import { Product } from '../models/product.model';

import {HttpClientModule} from '@angular/common/http';
import {AbstractMockObservableService} from './../services/AbstractMockObservableService.service';
import { AppComponent } from '../app.component';

class MockService extends AbstractMockObservableService {
  doStuff() {
    return this;
  }
}

let mockService;
beforeEach(() => {
  mockService = new MockService();
  TestBed.configureTestingModule({
    providers: [{provide: ProductService, useValue: ProductService }],
    declarations: [ AppComponent ]
  });
});
it('should retrieve products from the API via Get', () => {
      const testProducts : Product[]= [
        { id: 1, productName: "G1", modelCode: "SM1", serialNumber: "SN1"},
        { id: 2, productName: "G2", modelCode: "SM2", serialNumber: "SN2"},
        { id: 3, productName: "G3", modelCode: "SM3", serialNumber: "SN3"}
      ];
      mockService.getProducts().subscribe(products => {
        expect(products.length).toBe(3);
        expect(products).toEqual(testProducts);
      })

1 个答案:

答案 0 :(得分:0)

发生TypeError的原因是console.log()在分配之前正在工作。您可以设置setTimeout函数,以便将结果记录在控制台上