[英]How to write unit test case for api failure in angular 5?
嗨,我正在為Angular 5應用程序編寫單元測試用例。 我在我的項目中使用了api。 我正在為肯定和否定場景編寫單元測試用例。 我已經完成了積極的案例。 我正在努力編寫負面的測試案例。 例如我有ngoninit方法將數據加載到網格。 以下是我的代碼段。
ngOnInit() {
this.loadTenantsData();
this.columns = [
{ prop: "index", name: '#', width: 30, headerTemplate: this.statusHeaderTemplate, cellTemplate: this.statusTemplate, resizeable: false, canAutoResize: false, sortable: false, draggable: false },
{ prop: 'tenantname', name: 'Tenant', cellTemplate: this.nameTemplate, width: 200 },
{ name: '', width: 80, cellTemplate: this.actionsTemplate, resizeable: false, canAutoResize: false, sortable: false, draggable: false }
];
}
下面是loadTenantsData方法。
private loadTenantsData() {
this.tenantService.getTenants().subscribe(results => this.onTenantDataLoadSuccessful(results), error => this.onTenantDataLoadFailed(error));
}
以下是我的租戶服務。
getTenants(page?: number, pageSize?: number) {
return this.tenantEndpoint.getTenantsEndpoint<Tenant[]>(page, pageSize);
}
以下是我的租戶端點服務。
getTenantsEndpoint<T>(page?: number, pageSize?: number): Observable<T> {
return Observable.create(observer => {
var tenants = [{
'tenantid': 'bcdaedf3-fb94-45c7-b6a5-026ca4c53233',
'tenantname': 'BENZAAD.onmicrosoft.com'
}
];
if (!tenants) {
throw 'no tenants given'
}
observer.next(tenants);
});
}
下面是我的錯誤處理程序。
private onTenantDataLoadFailed(error: any) {
if (typeof error.error.title != 'undefined') {
this.alertService.stopLoadingMessage();
this.alertService.showStickyMessage("Load Error", `Unable to retrieve tenant data from the server.\r\nErrors: "${Utilities.getHttpResponseMessage(error)}"`,
MessageSeverity.error, error);
this.rows = [];
this.loadingIndicator = false;
this.alertService.showMessage(error.error.title, error.error.status, MessageSeverity.error);
}
}
我已經將所有單元測試用例文件放在下面。
describe('Component: TenantEditorComponent', () => {
let component: TenantEditorComponent;
let fixture: ComponentFixture<TenantEditorComponent>;
let submitEl: DebugElement;
let el: HTMLElement;
let scopename: DebugElement;
let scopeObject;
const mockResults = { /* whatever your results should look like ... */ };
const spyTenantService = jasmine.createSpyObj({ getTenants: of(mockResults), });
const spyAlertService = jasmine.createSpyObj({
stopLoadingMessage: null,
showStickyMessage: null,
showMessage: null
});
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
BrowserAnimationsModule,
HttpClientModule,
RouterTestingModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useClass: TranslateLanguageLoader
}
}),
NgxDatatableModule,
FormsModule,
UiSwitchModule,
TooltipModule.forRoot(),
ModalModule.forRoot(),
SimpleNotificationsModule.forRoot(),
HttpClientTestingModule
],
declarations: [
TenantEditorComponent,
SearchBoxComponent
],
providers: [
{
provide: LogMessages, useClass: LogMessagesMock
},
HtmlEncoding,
{
provide: Adal5Service, useClass: MockAdal5Service
},
TenantService,
UnitTestStorageOperations, TenantEndpoint,
TenantsEndpointMock,
AlertService,
AppContextService,
EndpointFactory,
NotificationsService,
AppTranslationService,
ConfigurationService,
LocalStoreManager,
{
provide: TenantEndpoint, useClass: TenantsEndpointMock
},
{ provide: TenantService, useValue: spyTenantService }
]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(TenantEditorComponent);
component = fixture.componentInstance;
});
it('ngOnInit should call onTenantDataLoadFailed() in case of error', () => {
var error = {
error: {
title: 'Tenant already exists',
status: '409'
}
}
spyOn(component, 'onTenantDataLoadFailed').and.callThrough();
debugger;
spyTenantService.getTenants.and.returnValue(ErrorObservable.create({ error }));
fixture.detectChanges();
expect(spyTenantService.getTenants).toHaveBeenCalledTimes(1);
expect(spyAlertService.stopLoadingMessage).toHaveBeenCalled();
expect(component.onTenantDataLoadFailed).toHaveBeenCalled();
expect(spyAlertService.showStickyMessage).toHaveBeenCalled();
expect(spyAlertService.showMessage).toHaveBeenCalled();
});
例如,出於任何原因,API均可歸檔。 在這種情況下,我的錯誤處理程序將被調用。 我想為這種情況編寫單元測試用例。 有人可以幫我編寫負面案例的單元測試用例嗎? 任何幫助,將不勝感激。 謝謝。
可以在成功(積極)的情況之后立即測試失敗(負面)的情況。 有很多方法可以完成此操作,而到目前為止您還沒有提供測試(spec)文件的外觀。 我將從為服務創建間諜開始,然后將它們添加到TestBed的提供程序中。
另一個關鍵是在設置成功或失敗的spy.returnValue()之前,不要調用Fixture.detectChanges(),因此請在it()規范定義中進行此操作。
像這樣:
import { of, throwError } from 'rxjs';
const mockResults = { /* whatever your results should look like ... */ };
const spyTenantService = jasmine.createSpyObj({getTenants: of(mockResults),});
const spyAlertService = jasmine.createSpyObj({
stopLoadingMessage: null,
showStickyMessage: null,
showMessage: null
});
let component: MyComponent;
let fixture: ComponentFixture<MyComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [MyComponent],
imports: [ ],
providers: [
{ provide: TenantService, useValue: spyTenantService },
{ provide: AlertService, useValue: spyAlertService },
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MyComponent);
component = fixture.componentInstance;
});
it('ngOnInit should initialize properly in positive (no error) case', () => {
fixture.detectChanges();
expect(component.results).toEqual(mockResults); // Something like this ...
/* I have no idea what this should look like - you said you have it working */
});
it('ngOnInit should call onTenantDataLoadFailed() in case of error', () => {
spyOn(component, 'onTenantDataLoadFailed').and.callThrough();
spyTenantService.getTenants.and.returnValue(throwError({error: {title: 'defined'}}));
fixture.detectChanges();
expect(spyTenantService.getTenants).toHaveBeenCalledTimes(1);
expect(spyAlertService.stopLoadingMessage).toHaveBeenCalled();
expect(component.onTenantDataLoadFailed).toHaveBeenCalled();
expect(spyAlertService.showStickyMessage).toHaveBeenCalled();
expect(spyAlertService.showMessage).toHaveBeenCalled();
});
更新:
感謝您提供規格文件。 正如我在上面的評論中提到的那樣,您應該刪除您在provider數組中為TenantService和AlertService提供的現有條目,因為您將通過間諜而不是原始服務來提供這些條目。 您還忘記了添加以下行:
{ provide: AlertService, useValue: spyAlertService }
因此,生成的providers數組應如下所示:
providers: [
{ provide: LogMessages, useClass: LogMessagesMock },
HtmlEncoding,
{ provide: Adal5Service, useClass: MockAdal5Service },
UnitTestStorageOperations,
AppContextService,
EndpointFactory,
NotificationsService,
AppTranslationService,
ConfigurationService,
LocalStoreManager,
{ provide: TenantEndpoint, useClass: TenantsEndpointMock },
{ provide: TenantService, useValue: spyTenantService },
{ provide: AlertService, useValue: spyAlertService }
]
注意:我還從陣列中的較早位置刪除了TenantEndpoint和TenantsendpointMock,因為稍后再指定-您只希望為要注入組件的每個提供程序輸入一個條目。 但是...我沒有看到TenantsEndpointMock的定義,所以我猜想它是在您上面粘貼的代碼片段之前聲明的,否則也會給您帶來錯誤。 :)
我認為這應該可以為您提供幫助,如果您有任何問題,請告訴我:
import { async, ComponentFixture, TestBed, fakeAsync, flush } from '@angular/core/testing';
import { ChatPageComponent } from './chat-page.component';
import { FormsModule } from '@angular/forms';
import { UserService } from '../user.service';
import { UserMockService } from '../test/user-mock.service';
import { HubService } from '../hub.service';
import { HubMockService } from '../test/hub-mock.service';
import { CommonHttpService } from '@matrixtools/common';
import { HttpMockService } from '../test/http-mock.service';
describe('ChatPageComponent', () => {
let component: ChatPageComponent;
let fixture: ComponentFixture<ChatPageComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ChatPageComponent],
providers: [{ provide: UserService, useClass: UserMockService },
{ provide: HubService, useClass: HubMockService },
{ provide: CommonHttpService, useClass: HttpMockService }],
imports: [FormsModule]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ChatPageComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
describe('ping function', () => {
it('should append a green message if hub connects', fakeAsync(() => {
// arrange
spyOn(component.hubConnection, 'invoke').and.returnValue(Promise.resolve('good promise'));
let expectedColor = 'green';
component.messages = [];
// act
component.ping();
flush();
// assert
let actualColor = component.messages[1].color;
expect(actualColor).toBe(expectedColor);
}));
it('should append a red message if hub connection fails', fakeAsync(() => {
// arrange
spyOn(component.hubConnection, 'invoke').and.returnValue(Promise.reject('bad promise'));
let expectedColor = 'red';
component.messages = [];
// act
component.ping();
flush();
// assert
let actualColor = component.messages[1].color;
expect(actualColor).toBe(expectedColor);
}));
});
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.