【问题标题】:How to fix 'TypeError: this.productService.getProducts is not a function' error?如何修复“TypeError:this.productService.getProducts 不是函数”错误?
【发布时间】:2019-05-06 08:27:32
【问题描述】:

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

在可视代码终端中运行 ng test 时,测试失败:“应该通过 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);
      })

【问题讨论】:

  • 有人可以帮忙吗?

标签: angular typescript testing mocking


【解决方案1】:

TypeError 的原因是 console.log() 在它被分配之前正在工作。您可以提供一个 setTimeout 函数,以便您可以将结果记录在控制台上

【讨论】:

  • 嗨 Munsheer,我在 ngOnInit 中使用应用程序组件尝试了以下操作: this.productService.getProducts().subscribe(products=> { //console.log(products); setTimeout(function(){ this.products = products.map(x => new Product(x)); },3000); }) 仍然得到与以前相同的错误。
猜你喜欢
  • 2019-12-25
  • 2021-06-12
  • 2019-07-01
  • 1970-01-01
  • 2019-11-26
  • 2019-07-10
  • 2020-07-25
  • 2021-01-10
  • 2019-11-22
相关资源
最近更新 更多