单元测试:Angular4:Jasmine:当控制从伪服务方法返回时,订阅中的响应未定义

我通过在spec文件中创建它的mock类来模拟服务 . 在我的组件中有一个调用数据服务的函数 . 当spec运行时,它成功转到mock方法但不返回数据,即observable.of中的内容 . 我得到的错误是'预期未定义为真正的' . 对于我的情况 .

spec文件


import { BaseRequestOptions, Http, HttpModule, Response, ResponseOptions } from '@angular/http';
import { MockBackend } from '@angular/http/testing';
import { AddserviceCenterRepairAuthorityComponent } from './add-serviceCenter-repair-authority.component';
import { TestBed, ComponentFixture, async, inject } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement, NO_ERRORS_SCHEMA } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { SelectItem, MultiSelectModule, CalendarModule } from 'primeng/primeng';
import { CoreUIModule } from 'core-ui';
import { RouterTestingModule } from '@angular/router/testing';
import { Router } from '@angular/router';
import { scooterRepairService } from '../services/scooterRepair.service';
import { StorageService } from 'core-shared/core.service';
import { serviceCenterRepairAdd } from '../models/serviceCenter-repair-add.model';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { Observable } from 'rxjs/Observable';

import { IMissingscooterRepair } from '../models/missing-scooter-repair';
import { serviceCenterRepairRecord } from '../models/serviceCenter-repair-record.model';
import { RepairClass } from '../models/repairClass.model';
import { RepairCode } from '../models/repairCode.model';
import { serviceCenterRepairSearch } from '../models/serviceCenter-repair-search.model';
import { scooterRepairSearch } from '../models/scooter-repair-search.model';
import { scooterRepairRecord } from '../models/scooter-repair-record.model';



fdescribe('AddserviceCenterRepairAuthorityComponent', () => {
    let fixture: ComponentFixture<AddserviceCenterRepairAuthorityComponent>;
    let de: DebugElement;
    let el: HTMLElement;
    let router: Router;
    let comp: AddserviceCenterRepairAuthorityComponent;

    class MockscooterRepairService {
        headers: Headers = new Headers();
        private help = '';
        private scooterRepairAuthorityApiurl = 'http://localhost:3000/scooterRepairAuthority';

        constructor() {
            this.headers.append('appuser', 'devnxd');
        }

        public submitserviceCenterRepair(serviceCenterRepairAddRecord): Observable<any> {
            if (serviceCenterRepairAddRecord.hasOwnProperty()) {
                return Observable.throw('Error occurred, please try again');
            } else {
                return Observable.of(
                    {
                        'isSuccess': true, 'results': [{ 'recordId': 1 }], 'recordId': 1
                    });


            }
        }


        clone(object: any) {
            return JSON.parse(JSON.stringify(object));
        }

        public getscooterInitials(): Observable<SelectItem[]> {

            return Observable.of(
                {

                });
        }

        public getThresholdValues(isAmountOnly: boolean): Observable<SelectItem[]> {
            return Observable.of(
                {

                });
        }
        public getRepairClassItems(): Observable<SelectItem[]> {
            return Observable.of(
                {

                });
        }
        public getRepairCodeItems(): Observable<SelectItem[]> {
            return Observable.of(
                {

                });
        }
        public getPercentageApprovalItems(): Observable<SelectItem[]> {
            return Observable.of(
                {

                });
        }


        public getUnitCountItems(scooterInitials: string[]): Observable<SelectItem[]> {
            return Observable.of(
                {

                });
        }

        public getscooterClassItems(scooterInitials: string[]): Observable<SelectItem[]> {
            return Observable.of(
                {

                });
        }

        public getFacilityItems(): Observable<SelectItem[]> {
            return Observable.of(
                {

                });
        }


        public searchscooterRepairs(scooterRepairSearch: scooterRepairSearch): Observable<scooterRepairRecord[]> {
            return Observable.of(
                {

                });
        }


        public searchserviceCenterRepairs(strFacility: string[], strStatusCode: string[], strthreshold: string[], lastUpdatedDate: Date,
            insertDate: Date, effectiveStartDate: Date, effectiveEndDate: Date) {
            return Observable.of(
                {

                });
        }



        public submitscooterRepair(scooterRepairRecord: scooterRepairRecord, isValidated: boolean = true): Observable<any> {
            return Observable.of(
                {

                });
        }
        public searchMissingscooterRepairs(): Observable<IMissingscooterRepair> {
            return Observable.of(
                {

                });
        }

        private getDefaultHeaders(): Headers {
            const headers: Headers = new Headers();
            // headers.append('appuser', this.auth.user.userName);
            headers.append('appuser', 'devvws');
            headers.append('Content-Type', 'application/json');
            //   headers.append('Cache-Control', 'no-cache');
            // headers.append('Pragma', 'no-cache');
            return headers;
        }



        private handleError(error: Response) {
            return Observable.throw(error.statusText || 'Server error');
        }

        private extractData(res: Response, isResultOnly: boolean = true) {
            const data = res.json();
            console.log(data);
            // const data = res.json(); // This will be used when actual service calling
            if (data.isSuccess) {
                return isResultOnly ? data.results : data;
            } else if (data.isException && data.errors.length > 0) {
                this.handleError(data.errors[0]);
            }
            return {};
        }
        convertFeatureListToNGPrimeDropdownOptions(list: any, labelKey, valueKey): SelectItem[] {
            const data = this.clone(list);
            const options: SelectItem[] = [];
            for (let i = 0; i < data.length; i++) {
                this.changeKeyName(data[i], labelKey, 'label');
                this.changeKeyName(data[i], valueKey, 'value');
                options.push(data[i]);
            }
            return options;
        }

        private changeKeyName(obj: any, oldKey: string, newKey: string): any {
            if (obj.hasOwnProperty(oldKey)) {
                obj[newKey] = obj[oldKey];
                delete obj[oldKey];
            }
            return obj;
        }

    }

    // async beforeEach
    beforeEach(async(() => {
        class RouterStub {
            navigateByUrl(url: string) { return url; }
        }




        TestBed.configureTestingModule({
            declarations: [AddserviceCenterRepairAuthorityComponent], // declare the test component
            schemas: [NO_ERRORS_SCHEMA],
            providers: [scooterRepairService, MockBackend, StorageService,
                BaseRequestOptions,
                {
                    provide: Http,
                    useFactory: (backend, options) => new Http(backend, options),
                    deps: [MockBackend, BaseRequestOptions]
                },
                { provide: scooterRepairService, useClass: MockscooterRepairService },
            ],
            imports: [BrowserAnimationsModule, FormsModule, MultiSelectModule, CalendarModule, CoreUIModule, RouterTestingModule]

        })
            .compileComponents();  // compile template and css
    }));

    // synchronous beforeEach -- used if component is having external templates
    beforeEach(() => {
        fixture = TestBed.createComponent(AddserviceCenterRepairAuthorityComponent);
        comp = fixture.componentInstance;
    });

    it('component is created', () => {
        expect(comp).toBeTruthy();
    });

    xit('unsuccessful should be true when serviceCenterRepairAddRecord is empty object', () => {

        comp.serviceCenterRepairAddRecord = <serviceCenterRepairAdd>{};
        const recordAddedSuccessfully = comp.onAddserviceCenterRepairClick();
        fixture.detectChanges();
        expect(recordAddedSuccessfully).toBe(2);
    });


    it('unsuccessful should be true when serviceCenterRepairAddRecord is not empty object', () => {

        comp.serviceCenterRepairAddRecord = <serviceCenterRepairAdd>{
            'facilityId': 1, 'statusCode': '200', 'thresholdAmount': 432,
            'effectiveStartDate': new Date(), 'effectiveEndDate': new Date(), 'builtEndDate': new Date()
        };
        comp.unsuccessful = 0;
        const recordAddedSuccessfully = comp.onAddserviceCenterRepairClick();
        fixture.detectChanges();
        expect(recordAddedSuccessfully).toBeTruthy();
    });


    xit('on cancel scooter repair click', () => {
        const spy = spyOn((<any>comp).router, 'navigateByUrl');
        comp.onCancelserviceCenterRepairClick();

        fixture.detectChanges();
        expect(spy).toHaveBeenCalledWith('cra');

    });
});

component.ts


onAddserviceCenterRepairClick() {
        this.scooterRepairService.submitserviceCenterRepair(this.serviceCenterRepairAddRecord).subscribe(
            response => this.submitedSuccess = response.recordId
            ,
            error => this.errorMessage = <any>error,
            () => {
                if (this.submitedSuccess === -1) {
                    alert('Record cannot be added');
                    this.unsuccessful = 2;
                } else {
                    this.unsuccessful = 1;
                    this.router.navigate(['cra'], { queryParams: { from: 'serviceCenterRepairSubmit' } });
                }
            }

        );

    }

当控制从伪服务类返回时,它应该具有从Observable.of返回的对象 . 但是在上面的component.ts代码中的响应变量是未定义的 .

请帮忙..!

回答(2)

2 years ago

您根据方法中的返回类型返回 array of objects . 但是你正在返回 only one object ,这导致了你的错误

return Observable.of([{

                   }]);

2 years ago

由于对mock类进行了原始调用,因此响应将始终为空 . 对于单元测试,检查this.submitedSuccess的值,它是一个实例变量 . 检查它是否等于从假Observable发送的-1或1 .