关于此 Jasmine 错误的澄清:this.http.get 不是函数澄清

Kid*_*001 2 automated-tests unit-testing jasmine karma-jasmine angular

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

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);
  })
Run Code Online (Sandbox Code Playgroud)

此部分从 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();
Run Code Online (Sandbox Code Playgroud)

})

完整错误:

    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)
Run Code Online (Sandbox Code Playgroud)

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

测试配置:

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


   })
Run Code Online (Sandbox Code Playgroud)

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

Jan*_*ker 5

你嘲笑你的 HttpService 吗?

\n\n

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

\n\n

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

\n\n

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

\n\n
 TestBed.configureTestingModule({\n    declarations: [YourComponentUnderTest],\n    providers: [\n        {provide: YourHttpService, useClass: MockYourHttpService} \n    ]\n});\nlet httpService = TestBed.get(YourHttpService);\n
Run Code Online (Sandbox Code Playgroud)\n\n

MockYourHttpService 将是一个看起来像原始服务的骨架,但没有花哨的实现。\n现在您可以根据需要模拟该服务

\n\n
spyOn(httpService, \'getData\').and.returnValue(yourMockedData)\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n

温暖的问候

\n