错误:: 0:0的错误是由于:METHOD_NAME不是一个函数-使用Karma和Jasmine进行的角度单元测试

时间:2019-03-04 06:10:08

标签: angular karma-jasmine

在为我的Angular代码运行Karma-Jasmine测试时,出现以下错误:

X should return Failed for invalid resource group
HeadlessChrome 0.0.0 (Windows 10 0.0.0) ResourceGroupFormComponent  should return Failed for invalid resource group FAILED
Error: Error in :0:0 caused by: this._subscriptionService.getSubscriptionByName is not a function
    at ViewWrappedError.ZoneAwareError (webpack:///~/zone.js/dist/zone.js:992:0 <- CloudShaper/config/spec-bundle.js:94039:33)
    at ViewWrappedError.BaseError [as constructor] (webpack:///~/@angular/core/src/facade/errors.js:22:0 <- CloudShaper/config/spec-bundle.js:33613:16)
    at ViewWrappedError.WrappedError [as constructor] (webpack:///~/@angular/core/src/facade/errors.js:87:0 <- CloudShaper/config/spec-bundle.js:33678:16)
    at new ViewWrappedError (webpack:///~/@angular/core/src/linker/errors.js:77:0 <- CloudShaper/config/spec-bundle.js:66796:16)
    at CompiledTemplate.proxyViewClass.DebugAppView._rethrowWithContext (webpack:///~/@angular/core/src/linker/view.js:650:0 <- CloudShaper/config/spec-bundle.js:107435:23)
    at CompiledTemplate.proxyViewClass.DebugAppView.detectChanges (webpack:///~/@angular/core/src/linker/view.js:623:0 <- CloudShaper/config/spec-bundle.js:107408:18)
    at ViewRef_.detectChanges (webpack:///~/@angular/core/src/linker/view_ref.js:170:0 <- CloudShaper/config/spec-bundle.js:67723:20)
    at ComponentFixture._tick (webpack:///~/@angular/core/bundles/core-testing.umd.js:196:0 <- CloudShaper/config/spec-bundle.js:954:36)
    at webpack:///~/@angular/core/bundles/core-testing.umd.js:210:45 <- CloudShaper/config/spec-bundle.js:968:53
    at ZoneDelegate.invoke (webpack:///~/zone.js/dist/zone.js:334:0 <- CloudShaper/config/spec-bundle.js:93381:26)
    at ProxyZoneSpec.onInvoke (webpack:///~/zone.js/dist/proxy.js:79:0 <- CloudShaper/config/spec-bundle.js:92943:39)
    at ZoneDelegate.invoke (webpack:///~/zone.js/dist/zone.js:333:0 <- CloudShaper/config/spec-bundle.js:93380:32)
    at Object.onInvoke (webpack:///~/@angular/core/src/zone/ng_zone.js:273:0 <- CloudShaper/config/spec-bundle.js:35275:37)
    at ZoneDelegate.invoke (webpack:///~/zone.js/dist/zone.js:333:0 <- CloudShaper/config/spec-bundle.js:93380:32)
    at Zone.run (webpack:///~/zone.js/dist/zone.js:126:0 <- CloudShaper/config/spec-bundle.js:93173:43)
    at NgZone.run (webpack:///~/@angular/core/src/zone/ng_zone.js:142:42 <- CloudShaper/config/spec-bundle.js:35144:62)
    at ComponentFixture.detectChanges (webpack:///~/@angular/core/bundles/core-testing.umd.js:210:0 <- CloudShaper/config/spec-bundle.js:968:29)
    at Object.<anonymous> (webpack:///ClientApp/app/components/resourcegroup/resourcegroup-form.component.spec.ts:98:0 <- CloudShaper/config/spec-bundle.js:114987:17)
    at ZoneDelegate.invoke (webpack:///~/zone.js/dist/zone.js:334:0 <- CloudShaper/config/spec-bundle.js:93381:26)
    at ProxyZoneSpec.onInvoke (webpack:///~/zone.js/dist/proxy.js:79:0 <- CloudShaper/config/spec-bundle.js:92943:39)
    at ZoneDelegate.invoke (webpack:///~/zone.js/dist/zone.js:333:0 <- CloudShaper/config/spec-bundle.js:93380:32)
    at Zone.run (webpack:///~/zone.js/dist/zone.js:126:0 <- CloudShaper/config/spec-bundle.js:93173:43)
    at Object.<anonymous> (webpack:///~/zone.js/dist/jasmine-patch.js:104:0 <- CloudShaper/config/spec-bundle.js:92643:34)
    at webpack:///~/@angular/core/bundles/core-testing.umd.js:96:0 <- CloudShaper/config/spec-bundle.js:854:21
    at ZoneDelegate.invoke (webpack:///~/zone.js/dist/zone.js:334:0 <- CloudShaper/config/spec-bundle.js:93381:26)
    at AsyncTestZoneSpec.onInvoke (webpack:///~/zone.js/dist/async-test.js:49:0 <- CloudShaper/config/spec-bundle.js:92238:39)
    at ProxyZoneSpec.onInvoke (webpack:///~/zone.js/dist/proxy.js:76:0 <- CloudShaper/config/spec-bundle.js:92940:39)
    at ZoneDelegate.invoke (webpack:///~/zone.js/dist/zone.js:333:0 <- CloudShaper/config/spec-bundle.js:93380:32)
    at Zone.run (webpack:///~/zone.js/dist/zone.js:126:0 <- CloudShaper/config/spec-bundle.js:93173:43)
    at AsyncTestZoneSpec._finishCallback (webpack:///~/@angular/core/bundles/core-testing.umd.js:91:0 <- CloudShaper/config/spec-bundle.js:849:29)
    at webpack:///~/zone.js/dist/async-test.js:38:0 <- CloudShaper/config/spec-bundle.js:92227:31
    at ZoneDelegate.invokeTask (webpack:///~/zone.js/dist/zone.js:367:0 <- CloudShaper/config/spec-bundle.js:93414:31)
    at Zone.runTask (webpack:///~/zone.js/dist/zone.js:166:0 <- CloudShaper/config/spec-bundle.js:93213:47)
    at ZoneTask.invoke (webpack:///~/zone.js/dist/zone.js:420:0 <- CloudShaper/config/spec-bundle.js:93467:38)
    at data.args.(anonymous function) (webpack:///~/zone.js/dist/zone.js:1581:0 <- CloudShaper/config/spec-bundle.js:94628:29)

触发此单元测试的代码是:

resourcegroup-form.component.spec.ts:

it("should return Failed for invalid resource group", () => {
        //Pass invalid solution, simulate validate button click
        component.validateResourceGroup("18d05e50-d339-4ff9-a1e5-b90459e2d9cc", "18d05e50-d339-4ff9-a1e5-b90459e2d9cc");
        fixture.detectChanges();

        //Verify response in dialog box
        let de: DebugElement = fixture.debugElement.query(By.css('#validationHeader'));
        let el: HTMLElement = de.nativeElement;
        expect(el.textContent.indexOf("Failed") > 0).toEqual(true);
    });

此外,从测试方法中调用的resourcegroup-form.component.ts的validateResourceGroup方法是:

resourcegroup-form.component.ts:

validateResourceGroup(solutionId?: string, rgId?: string) {
        this.busy = true;
        //Check if there are unsaved changes
        if (this.isDraft) {
            this.busy = false;
            this._toaster.Notify("error", "There are unsaved changes for this resource group. Please save before validating.");

            this.hasValidationError = true;
            this.validationModal.show();
        }
        else {
            //Validate solution & rg provided, otherwise get active solution & rg.
            let solutionToValidate = solutionId ? solutionId : this._solutionManagementService.GetActiveSolution().id;
            let rgToValidate = rgId ? rgId : this._solutionManagementService.GetActiveResourceGroup().id;

            this._deploymentService.validate(solutionToValidate, rgToValidate)
                .subscribe(response => {

                    //Convert dto to value object
                    let validationResult = new ValidateResult(
                        response.result.name,
                        response.result.type,
                        response.result.properties
                    );

                    if (validationResult.name == "Succeeded") {
                        this.validationResult = null;
                        this.hasValidationError = false;
                    }
                    else {
                        this.validationResult = validationResult;
                        this.hasValidationError = true;
                        this.validationErrorType = "error";

                        let errorProperties = this.validationResult.properties;
                        if (errorProperties) {
                            this.setValidationErrorProperties(errorProperties);
                        }
                        else {
                            //properties missing
                        }
                    }
                    this.validationModal.show();
                    this.busy = false;
                },
                (error: any) => {
                    this.busy = false;
                    this._toaster.Notify("error", "An error occured while validating the solution.");
                });
        }
    }

现在,根据错误,getSubscriptionName方法不是有效的函数。我不确定为什么会这样,因为我也嘲笑了这个方法(下面的代码片段)。如果有人可以在这方面帮助我,我将不胜感激。

subscription.service.ts:

getSubscriptionByName(subscriptionName: string): Observable<Envelope<SubscriptionListItem>> {
        let url: string = 'api/subscriptions/getSubscriptionByName';
        let headers = new Headers({ 'Content-Type': 'application/json' });
        let options = new RequestOptions({
            headers: headers
        });

        return this._http.post(url, JSON.stringify(subscriptionName), options)
            .map(response => response.json() as Envelope<SubscriptionListItem>)
            .do(subs => {
                return subs;
            });
    }

subscription.service.mock.ts:

import { Injectable } from '@angular/core';
import { AzureSubscription, SubscriptionListItem } from '../models/Subscription';
import { Observable, Subject } from 'rxjs'

@Injectable()
export class SubscriptionServiceMock {
    // Add more fields and methods as needed.
    // GUIDs were randomly generatored and DO NOT correspond to actual data
    public subscriptions: Array<AzureSubscription> = [
        <AzureSubscription>{
            id: "bf979e1c-1185-4be8-9c2f-a8d0dd71d4b6",
            name: "Test Subscription 1",
            client: "xxx",
            owner: "unique.name@xxx.com",
            authorizedUsers: [],
            createdBy: "andrew.l.dimatteo@xxx.com",
            subscriptionId: "3f05db6c-c344-4f37-ba74-eb5f8131eb7e",
            clientId: "5b92ab12-2352-4453-a4e2-f1b8727ba29d",
            tenantId: "d7fcc713-34d9-4815-9ea9-e782b29e1554",
            clientSecret: "secret1"
        },
        <AzureSubscription>{
            id: "ec08e736-650c-45a1-9c6f-aab410e12ce3",
            name: "Test Subscription 2",
            client: "xxx",
            owner: "unique.name@xxx.com",
            authorizedUsers: ["andrew.l.dimatteo@xxx.com", "andrew.l.dimatteo@yyy.com"],
            createdBy: "unique.name@xxx.com",
            subscriptionId: "3d8fbf527-3587-4309-bf09-20901bebaa25",
            clientId: "75ff2e22-9d83-4d68-a174-dbc227fa19b0",
            tenantId: "01e5f9dd-7aa4-4580-ac35-c64699f29bdb",
            clientSecret: "secret2"
        }
    ];

    public Subscriptions: Subject<Array<AzureSubscription>> = new Subject<Array<AzureSubscription>>();

    getSubscriptionByName(subscriptionName: string): Observable<SubscriptionListItem> {
        let subscription = this.subscriptions.find(it => it.name == subscriptionName);
        return Observable.of(subscription);
    }

}

0 个答案:

没有答案