在为我的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);
}
}