【问题标题】:TypeError: Cannot read property 'Symbol(Symbol.iterator)' of undefined RxJSTypeError:无法读取未定义 RxJS 的属性“Symbol(Symbol.iterator)”
【发布时间】:2017-06-20 06:43:09
【问题描述】:

我想触发这个 catch 块并确认 handleError() 运行:

@Injectable()
export class JwtService {
    private actionUrl: string;
    private headers: Headers;


    constructor(private http: Http, private configurationService: ConfigurationService, private _utilsSvc: UtilitiesService) {}

    getToken() {
        if (this.configurationService.config) {
            return this.http.post(this.configurationService.config.jwtUrl, { "brand": "IAG" })
                .map(this._utilsSvc.parseJson)
                .catch(this.handleError);
        }   
    }

    handleError(error: any) {
        let errorStatus = error.status;
        return Observable.throw(errorStatus);
    }
}

utilsSvc 类:

@Injectable()
export class UtilitiesService {

    constructor(private http: Http) { }

    fetchFile(url) {
        return this.http.get(url)
            .toPromise();
    }

    parseJson(response: Response) {
        return response.json();
    }
}

我正在尝试传递无效的 json 以导致错误被捕获:

it("Should handle error", () => {
    let resOp = new ResponseOptions({
        body: "invalid json"
    });
    mockHttpResponse = new Response(resOp);
    mockBackend.connections.subscribe(connection => {
        connection.mockRespond(mockHttpResponse);
    });
    spyOn(jwtService, 'handleError');
    jwtService.getToken().subscribe((res) => {
        expect(jwtService.handleError).toHaveBeenCalled();
    });
});

我收到此错误:

TypeError: 无法读取未定义的属性“Symbol(Symbol.iterator)”

如何让catch块捕捉到错误?

这是我的整个测试文件:

/// <reference path="../../typings/globals/es6-shim/index.d.ts"/>
/// <reference path="../../typings/globals/jasmine/index.d.ts" />
import { inject, TestBed, ComponentFixture } from "@angular/core/testing";
import { RouterTestingModule } from "@angular/router/testing";
import { Headers, HttpModule, BaseRequestOptions, XHRBackend, Response, Http, ResponseOptions } from "@angular/http";
import { MockBackend, MockConnection } from "@angular/http/testing";
import { Component, DebugElement } from "@angular/core";
import { By } from '@angular/platform-browser';
import "rxjs/add/operator/toPromise";
import { Observable } from "rxjs/Rx";
import "rxjs/add/operator/toPromise";

import { AuthenticationLibrary } from "../../app/services/authenticationLibrary.service";
import { ConfigurationService } from "../../app/services/configuration.service";
import { FrontEndLoggingService } from "../../app/services/frontEndLogging.service";
import { JwtService } from "../../app/services/jwt.service";
import { UtilitiesService } from "../../app/services/utilities.service";

describe("Authentication service", () => {

    let mockBackend;
    let jwtService;
    let configSvc;
    let http;
    let feLogSvc;
    let mockHttpResponse;

    beforeEach(() => {
        TestBed.configureTestingModule({
            imports: [HttpModule],
            providers: [
                { provide: XHRBackend, useClass: MockBackend },
                ConfigurationService,
                FrontEndLoggingService,
                JwtService,
                UtilitiesService
            ]
        });

        mockBackend = TestBed.get(XHRBackend);
        http = new Http(mockBackend, new BaseRequestOptions);
        feLogSvc = TestBed.get(FrontEndLoggingService);
        configSvc = TestBed.get(ConfigurationService);
        configSvc.config = {
            enableFrontEndDebugLogs: true,
            baseUrl: "www.someurl.com",
            providerEndpoint: "someMachine",
            categoriesEndpoint: "someCatEndpoint"
        }

        jwtService = new JwtService(
            TestBed.get(Http),
            configSvc,
            TestBed.get(UtilitiesService)
        )




    });

    it("Should get token", () => {        
        let resOp = new ResponseOptions({
            body: {
                "token": "Bearer ABC123",
                "brand": "AMI"
            }
        })
        mockHttpResponse = new Response(resOp)
        mockBackend.connections.subscribe(connection => {
            connection.mockRespond(mockHttpResponse);
        });
        jwtService.getToken().subscribe(response => {
            expect(response.token).toBe("Bearer ABC123");
        });
    });

    it("Should handle error", () => {
        let resOp = new ResponseOptions({
            body: "sdvhfujvn"
        });
        mockHttpResponse = new Response(resOp);
        mockBackend.connections.subscribe(connection => {
            connection.mockRespond(mockHttpResponse);
        });
        spyOn(jwtService, 'handleError');
        jwtService.getToken().subscribe((res) => {
            expect(jwtService.handleError).toHaveBeenCalled();
        });
    });
});

【问题讨论】:

  • 你能展示一下你是如何构造jwtService的

标签: json angular jasmine rxjs


【解决方案1】:

问题在这里

spyOn(jwtService, 'handleError');

spyOn 将覆盖此方法,因此当 catch 期望您返回一个可观察对象时它不会返回任何内容。

要解决此问题,您需要从该方法返回

it("Should handle error", () => {
        let resOp = new ResponseOptions({
            body: "sdvhfujvn"
        });
        mockHttpResponse = new Response(resOp);
        mockBackend.connections.subscribe(connection => {
            connection.mockRespond(mockHttpResponse);
        });
        spyOn(jwtService, 'handleError').and.callFake(function () {
            return Observable.from("fake error");
        });
        jwtService.getToken()
            .subscribe((res) => {
                expect(jwtService.handleError).toHaveBeenCalled();
            });
    });

这个测试会起作用,但我不确定这个测试是否有意义

【讨论】:

  • 谢谢。是否可以不更改getToken 方法?这就是我正在测试的方法。严格来说我不应该改变它。
  • 这个方法是无效的 :) 但是有可能我要求你发布你的规范的完整配置,我想看看你如何在你的测试中构建服务,特别是你如何提供私有 configurationService:ConfigurationService
  • 干杯,我现在已经发布了整个规范文件。
  • 我仍然遇到同样的错误。请注意,我的规范文件中的顶部测试确实通过了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-11-03
  • 1970-01-01
  • 2019-04-29
  • 1970-01-01
  • 2017-04-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多