Я пишу тест с использованием Жасмин для приложения Angular 8. Я написал тест для подтверждения диалога. У меня есть три условия для проверки при отображении диалогового окна подтверждения. Сбросить, отклонить и одобрить. В тот момент, когда я запускаю npm тестовое покрытие для тестового покрытия, его выделение остальной части кода ниже не рассматривается. Я думал, что мой тест («должен вызвать диалог подтверждения отказа») должен был покрыть это. Я не уверен, почему тесты не охватывают немного? Может ли кто-нибудь помочь
if (type === 'Approve') {
this.confirmationDialog.show(this.approvalMessage, type, () => this.confirm(type));
} else if (type === 'Reset') {
this.confirmationDialog.show(this.resetMessage, type, () => this.confirm(type));
} else if (type === 'Reject') {
this.confirmationDialog.show(this.rejectMessage, type, () => this.confirm(type));
}
Код компонента
export class ApproveComponent {
public showMessage = false;
public message: string;
public body = 'Loading content for approval...';
public loading = true;
public permissions: NgxPermissionsObject;
private id: string;
private type: string;
private approvalMessage = 'Are you sure the information is correct and you want to approve?';
private resetMessage = 'Are you sure you want to reset this approval back to the start?';
private rejectMessage = 'Are you sure you want to reject this approval? ' +
'Rejecting an approval is permanent and will close this process and prevent it progressing further.';
constructor(
private router: Router,
private route: ActivatedRoute,
private service: ApprovalsService,
private ngxPermissionsService: NgxPermissionsService,
private messageService: MessageService,
public confirmationDialog: ConfirmationDialogService) {
this.route.params.subscribe(params => {
this.id = params['id'];
this.type = params['type'];
this.loading = true;
this.service.get(this.type, this.id).then(x => {
if (!x) { return; }
this.loading = false;
this.body = x.body;
});
});
this.permissions = this.ngxPermissionsService.getPermissions();
}
public confirmation = (type: 'Reset' | 'Reject' | 'Approve') => {
if (!this.showMessage
&& ((type === 'Approve' && this.permissions.ViewNotes)
|| (type !== 'Approve'))) {
this.showMessage = true;
return;
}
if (!this.message
&& ((type === 'Approve' && this.permissions.ViewNotes)
|| (type !== 'Approve'))) {
this.messageService.add('Message is required.', 'warning');
return;
}
if (type === 'Approve') {
this.confirmationDialog.show(this.approvalMessage, type, () => this.confirm(type));
} else if (type === 'Reset') {
this.confirmationDialog.show(this.resetMessage, type, () => this.confirm(type));
} else if (type === 'Reject') {
this.confirmationDialog.show(this.rejectMessage, type, () => this.confirm(type));
}
}
public confirm = (type: 'Reset' | 'Reject' | 'Approve') => {
let promise;
if (type === 'Reset') {
promise = this.service.reset(this.id, this.type, this.message);
} else if (type === 'Reject') {
promise = this.service.reject(this.id, this.type, this.message);
} else if (type === 'Approve') {
promise = this.service.approve(this.id, this.type, this.message);
}
promise.then(() => {
this.messageService.add(`Successfully ${type}.`, 'info');
this.navigateToApprovalList();
});
}
private navigateToApprovalList = () => this.router.navigate(['/approvals']);
}
Тестовый компонент
describe('ApproveComponent', () => {
let component: ApproveComponent;
let injector: TestBed;
let fixture: ComponentFixture<ApproveComponent>;
const mockService: ApprovalsService = <ApprovalsService>{
approve: (id: string, type: string, message: string) => <Promise<any>>{},
reset: (id: string, type: string, message: string) => <Promise<any>>{},
reject: (id: string, type: string, message: string) => <Promise<any>>{},
get: (type: string, id: string) => <Promise<any>>{},
};
const mockRoute = { params: of({ id: '123', type: 'test' }), snapshot: {} };
function setupComponent(getResult: any = {}) {
spyOn(mockService, nameof<ApprovalsService>('approve')).and.returnValue(Promise.resolve({}));
spyOn(mockService, nameof<ApprovalsService>('reset')).and.returnValue(Promise.resolve({}));
spyOn(mockService, nameof<ApprovalsService>('reject')).and.returnValue(Promise.resolve({}));
spyOn(mockService, nameof<ApprovalsService>('get')).and.returnValue(Promise.resolve(getResult));
TestBed.configureTestingModule({
imports: [
DxTextAreaModule,
DxButtonModule,
SharedModule,
RouterTestingModule.withRoutes([{ path: 'approvals', component: ApproveComponent }])
],
declarations: [ApproveComponent],
providers: [
{ provide: ApprovalsService, useValue: mockService },
{ provide: ActivatedRoute, useValue: mockRoute },
{ provide: MessageService, useClass: MockMessageService },
{ provide: ConfirmationDialogService, useValue: ConfirmationDialogServiceMock },
{ provide: NgxPermissionsService, useClass: MockNgxPermissionsService }
]
})
.compileComponents();
fixture = TestBed.createComponent(ApproveComponent);
injector = getTestBed();
component = fixture.componentInstance;
spyOn((<any>component).router, 'navigate').and.returnValue(true);
fixture.detectChanges();
}
it('should create and call get', () => {
setupComponent();
expect(component).toBeTruthy();
expect(mockService.get).toHaveBeenCalled();
});
it('should call get and do not set body on empty result', () => {
setupComponent(null);
expect(component).toBeTruthy();
expect(component.body).toBe('Loading content for approval...');
});
it('should call confirmation dialog when accept confirmation is called', () => {
setupComponent();
const dialogService = injector.get(ConfirmationDialogService);
const dialogServiceSpy = spyOn(dialogService, 'show').and.callThrough();
component.showMessage = true;
component.message = 'Approved because potato';
fixture.ngZone.run(() => component.confirmation('Approve'));
expect(dialogServiceSpy).toHaveBeenCalled();
expect(dialogServiceSpy).toHaveBeenCalled();
});
it('should call reject confirmation dialog', () => {
setupComponent();
const dialogService = injector.get(ConfirmationDialogService);
const dialogServiceSpy = spyOn(dialogService, 'show').and.callThrough();
component.showMessage = true;
component.message = 'rejected because potato';
fixture.ngZone.run(() => component.confirmation('Reject'));
expect(dialogServiceSpy).toHaveBeenCalled();
expect(mockService.reject).toHaveBeenCalled();
});
it('should call reset confirmation dialog', () => {
setupComponent();
const dialogService = injector.get(ConfirmationDialogService);
const dialogServiceSpy = spyOn(dialogService, 'show').and.callThrough();
component.showMessage = true;
component.message = 'rejected because potato';
fixture.ngZone.run(() => component.confirmation('Reset'));
expect(dialogServiceSpy).toHaveBeenCalled();
expect(mockService.reset).toHaveBeenCalled();
});
it('should set showMessage when reject is called', () => {
setupComponent();
component.showMessage = false;
fixture.ngZone.run(() => component.confirmation('Reject'));
expect(component.showMessage).toBe(true);
expect(mockService.reject).not.toHaveBeenCalled();
});
it('should not call service when reject is called and message is empty', () => {
setupComponent();
component.showMessage = true;
component.message = '';
fixture.ngZone.run(() => component.confirmation('Reject'));
expect(mockService.reject).not.toHaveBeenCalled();
});
});