【发布时间】:2019-12-18 18:00:51
【问题描述】:
我有一项服务可以执行以下操作:
updateProperties(properties: any) {
return this.http.put(environment.adminApiURLPrefix+'api/v1/properties', properties);
}
在我的组件中,我有两个对象,providers 和 providerProperties。 Providers 包含 API 提供者及其状态的键值对,而 providerProperties 是从 API 返回的实际响应(必须存储,因为任何后续请求都需要整个对象)。
import { Component, OnInit } from '@angular/core';
import { ProviderService } from '../../services/provider.service';
import { Status } from 'src/app/models/status.enum';
import { AlertService } from 'src/app/services/alert.service';
@Component({
selector: 'app-providers',
templateUrl: './providers.component.html',
styleUrls: ['./providers.component.scss']
})
export class ProvidersComponent implements OnInit {
providers: any;
providerProperties: any;
status: Status;
constructor(private providerService: ProviderService, private alertService: AlertService) {
this.providers = {
'API1': false,
'API2': false,
'API3': false
}
this.status = Status.Loading;
}
ngOnInit() {
this.providerService.getProperties().subscribe((response: any) => {
this.setProviderValues(response);
this.status = Status.Ready;
},
error => {
this.alertService.error('Error');
this.status = Status.Error;
})
}
setProviderValues(response: any) {
this.providerProperties = response;
Object.keys(this.providers).forEach(key => {
let providerStatus: string = this.providerProperties[key.toLowerCase() + '.enabled'];
if(providerStatus == 'true' || providerStatus == 'false') {
this.providers[key] = providerStatus == 'true' ? true : false;
} else {
this.alertService.error('Error.');
this.status = Status.Error;
return;
}
});
}
changeProviderProperty(provider: string, isEnabled: boolean) {
let providerKey: string = this.providerDisplayNameToPropertyKey(provider);
let tempProviderProperties = Object.assign({}, this.providerProperties);
tempProviderProperties[providerKey] = isEnabled ? true : false;
this.providerService.updateProperties(tempProviderProperties).subscribe(
response => {
this.setProviderValues(response);
this.alertService.success('Successfully '+ (isEnabled ? 'Enabled ' : 'Disabled ') + provider);
},
err => {
if(err['status'] == 0) {
this.alertService.error('Error');
} else {
let errorArray = err['error']['Errors']['Error'];
for(let errorKey in errorArray) {
let errorValue = errorArray[errorKey];
this.alertService.error('Error Updating Properties: ' + errorValue['ReasonCode'] + ' ' + errorValue['Description']);
}
}
}
)
}
providerDisplayNameToPropertyKey(provider: string) {
return provider.toLowerCase() + '.enabled';
}
}
我有以下测试:
import { async, ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { ProvidersComponent } from './providers.component';
import { ProviderService } from 'src/app/services/provider.service';
import { of, Observable, throwError } from 'rxjs';
import { AlertComponent } from '../shared/alert/alert.component';
import { RouterTestingModule } from '@angular/router/testing';
import { AlertService } from 'src/app/services/alert.service';
import { HttpErrorResponse } from '@angular/common/http';
describe('ProvidersComponent', () => {
let component: ProvidersComponent;
let providerService: ProviderService;
let alertService: AlertService;
let fixture: ComponentFixture<ProvidersComponent>;
let getPropertiesSpy: jasmine.Spy<() => Observable<String>>;
let changeProviderPropertySpy: jasmine.Spy<(provider: string, isEnabled: boolean) => Promise<void>>;
let providerProperties:any;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
ProvidersComponent,
AlertComponent
],
imports: [
HttpClientTestingModule,
RouterTestingModule
],
providers: [
ProviderService,
AlertService
]
})
.compileComponents();
}));
beforeEach(() => {
providerService = TestBed.get(ProviderService);
alertService = TestBed.get(AlertService);
fixture = TestBed.createComponent(ProvidersComponent);
providerProperties = {
'api1.enabled': 'true',
'api2.enabled': 'true',
'api3.enabled': 'false',
};
component = fixture.componentInstance;
component.providers = {
'API1': false,
'API2': false,
'API3': false
};
getPropertiesSpy = spyOn(providerService, 'getProperties').and.callFake(() => {
return of(providerProperties);
});
changeProviderPropertySpy = spyOn(component, 'changeProviderProperty');
fixture.detectChanges();
});
it('should enable provider', fakeAsync(() => {
spyOn(providerService, 'updateProperties').and.returnValue(of({
'api1.enabled': 'true',
'api2.enabled': 'false',
'api3.enabled': 'false'
}));
component.changeProviderProperty('API1', true);
fixture.detectChanges();
expect(component.providers['API1']).toEqual(true);
}));
});
由于某种原因,对象的状态不会改变。我很确定 observable 没有被订阅或者我没有等待响应。
更新 在监视提供程序服务并检查它是否在我调用 changeProviderProperties 后被调用后,结果发现它从未被调用过。
更新 2 窥探 providerDisplayNameToPropertyKey 方法,发现无论出于何种原因都没有调用它。
【问题讨论】:
-
您可以随时通过
tap操作员或订阅方法中的一些控制台登录来检查您是否正确订阅。
标签: javascript angular typescript jasmine