对此茉莉花错误的澄清:this.http.get不是函数澄清

时间:2018-07-05 18:55:19

标签: angular unit-testing jasmine automated-tests karma-jasmine

当我尝试对组件类中使用服务的任何函数进行单元测试时,都会遇到此错误。这是我功能的一部分。

loadUser() {
this.httpService.getData(AppConfig.URL_UserById + "?UserID=" + this.userId)
  .catch((error: Response | any) => {
    this.showAlertWindow(this.exceptionMessage);
    console.error(error.message || error);
    return Observable.throw(error.message || error);
  })

这部分从URL检索数据,如果有问题则抛出错误。 getData是发出get请求的服务。我只是想测试是否正在调用showAlertWindow方法。现在,我很确定我的测试代码是正确的,但是我必须缺少一些东西才能收到此错误。我猜茉莉不知道该如何处理this.httpService.getData(...)这行。

测试:

  fit('should have getUsers() call showAlertWindow', () => {

 let window = spyOn(userComponent, 'showAlertWindow');

 userComponent.loadUser(); //Fails here

 expect(window).toHaveBeenCalled();

})

完全错误:

    Error: Cannot call Promise.then from within a sync test.
Error: Cannot call Promise.then from within a sync test.
    at SyncTestZoneSpec.webpackJsonp../node_modules/zone.js/dist/zone-testing.js.SyncTestZoneSpec.onScheduleTask (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-testing.js:365:1)
    at ZoneDelegate.webpackJsonp../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:401:1)
    at Zone.webpackJsonp../node_modules/zone.js/dist/zone.js.Zone.scheduleTask (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:232:1)
    at Zone.webpackJsonp../node_modules/zone.js/dist/zone.js.Zone.scheduleMicroTask (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:252:1)
    at scheduleResolveOrReject (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:862:1)
    at ZoneAwarePromise.then (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:962:1)
    at ApplicationInitStatus.webpackJsonp../node_modules/@angular/core/esm5/core.js.ApplicationInitStatus.runInitializers (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/esm5/core.js:3580:1)
    at TestBed.webpackJsonp../node_modules/@angular/core/esm5/testing.js.TestBed._initIfNeeded (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/esm5/testing.js:1011:1)
    at TestBed.webpackJsonp../node_modules/@angular/core/esm5/testing.js.TestBed.get (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/esm5/testing.js:1050:1)
    at Function.webpackJsonp../node_modules/@angular/core/esm5/testing.js.TestBed.get (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/esm5/testing.js:834:1)

如果有人可以让我对这个错误背后的含义有一些了解,那就太好了。谢谢。

测试配置:

import { HttpService } from '../../services/http.service';
import { TestBed, async, inject, fakeAsync, ComponentFixture } from "@angular/core/testing";
import { UserComponent } from './user.component';
import { Observable } from 'rxjs';


    fdescribe('User Component', () => {
    let httpService: HttpService;
    let userComponent: UserComponent

beforeEach(async() => {
    TestBed.configureTestingModule({
      declarations: [
        UserComponent, 
      ],
 providers: [
  HttpService,
 ],
 }).compileComponents();
  });
   beforeEach(() => {
 userComponent = fixture.componentInstance;
 httpService = TestBed.get(HttpService);

 fit('should have getUsers() call showAlertWindow', () => {

     let window = spyOn(userComponent, 'showAlertWindow');

     userComponent.loadUser();

     expect(window).toHaveBeenCalled();


   })

编辑:有两种可能的解决方案。我通过监视服务并返回一个可观察值解决了该错误。 spyOn(httpService, 'getData).and.returnValue(Observable.of('test'));或更实用的JanRecker解决方案。

1 个答案:

答案 0 :(得分:1)

您模拟了HttpService吗?

如果您在UnitTests中实例化了服务,则它将尝试处理此方法。我认为,在您的HttpService中,您使用的是Angular HTTPClient Service(我想是因为出现错误“ this.http.get”)

现在,您实例化了您的服务,但没有实例化其依赖关系。并且,在UnitTests中,您必须手动实例化所有内容。 因此,在您的测试中,没有启动并运行Angular“ http”服务。

我习惯于嘲笑一切,这不是我的组件/服务正在测试中。 所以在您的情况下,我会做类似的事情

 TestBed.configureTestingModule({
    declarations: [YourComponentUnderTest],
    providers: [
        {provide: YourHttpService, useClass: MockYourHttpService} 
    ]
});
let httpService = TestBed.get(YourHttpService);

MockYourHttpService将是一个看起来像原始服务的框架,但没有精美的实现。 现在,您可以随意模拟该服务

spyOn(httpService, 'getData').and.returnValue(yourMockedData)

或者,您可以导入HttpClientTestingModule,并模拟“ this.http.get”调用,但是组件单元测试将隐式测试httpService的某些部分。

热烈的问候