Поведение-субъект-шпион и применение .pipe - PullRequest
0 голосов
/ 06 июля 2019

Я запускаю тест Units для моего компонента, когда при попытке смоделировать один атрибут типа BehaviorSubject в моем сервисе я получил эту ошибку.Msgstr "Ошибка типа: невозможно прочитать свойство 'pipe' из неопределенного".

Я попытался смоделировать один атрибут как BehaviorSubject из моего сервиса в моем компоненте,

component.ts

export class ShowFiltersComponent implements OnInit, OnDestroy {
    private _unsubscribeAll: Subject<any>;
    filterSelected = [];
    constructor(
        private _chr: ChangeDetectorRef,
        private _pmService: PMService
    ) {
        this._unsubscribeAll = new Subject();
    }

    ngOnInit() {
        this._pmService.onFilterShowSelected
            .pipe(takeUntil(this._unsubscribeAll))
            .subscribe(res => {
                this.filterSelected = res;
                this._chr.detectChanges();
            });
    }
    ngOnDestroy(): void {
        // Unsubscribe from all subscriptions
        this._unsubscribeAll.next();
        this._unsubscribeAll.complete();
    }
}

pmService.service.ts

export class PMService {

    _onFilterShowSelected: BehaviorSubject<any>;

    constructor(private _http: HttpClient) {
      this._onFilterShowSelected = new BehaviorSubject({});
    }

    get onFilterShowSelected(): BehaviorSubject<any> {
        return this._onFilterShowSelected;
    }
....
}

component.spect.ts

describe("ShowFiltersComponent", () => {
    let component: ShowFiltersComponent;
    let service: PatientManagementService;
    let fixture: ComponentFixture<ShowFiltersComponent>;
    let httpMock: HttpClient;


    beforeEach(async(() => {
        const sp = spyOnProperty(
            new PMService(httpMock),
            "onFilterShowSelected",
            "get"
        ).and.returnValue(of({}));
        TestBed.configureTestingModule({
            schemas: [NO_ERRORS_SCHEMA],

            declarations: [ShowFiltersComponent],
            imports: [HttpClientModule],
            providers: [
                {
                    provide: PMService,
                    useValue: sp
                }
            ]
        }).compileComponents();
    }));

    beforeEach(() => {
        fixture = TestBed.createComponent(ShowFiltersComponent);
        component = fixture.componentInstance;
        fixture.detectChanges();
    });

    it("should create", () => {
        expect(component).toBeTruthy();
    });
});

1 Ответ

0 голосов
/ 06 июля 2019

Я бы выбрал другой подход и создал бы stub что-то вроде:

describe("ShowFiltersComponent", () => {
    let component: ShowFiltersComponent;
    let service: PatientManagementService;
    let fixture: ComponentFixture<ShowFiltersComponent>;
    let httpMock: HttpClient;


    beforeEach(async(() => {
        TestBed.configureTestingModule({
            schemas: [NO_ERRORS_SCHEMA],
            declarations: [ShowFiltersComponent],
            imports: [HttpClientModule],
            providers: [
                {
                    provide: PMService,
                    useClass: PMServiceStub
                }
            ]
        }).compileComponents();
    }));

    beforeEach(() => {
        fixture = TestBed.createComponent(ShowFiltersComponent);
        component = fixture.componentInstance;
        fixture.detectChanges();
    });

    it("should create", () => {
        expect(component).toBeTruthy();
    });
});


class PMServiceStub{
    get onFilterShowSelected(): BehaviorSubject<any> {
        return of({
           // ur desired object
        });
    }
}

На боковой ноте вместо того, чтобы выставлять все BeahaviorSubject (что позволяет этому компонентучтобы получить доступ к next()), вы можете вернуть его как .asObservable(), что не позволяет вызвать next(), если компонент явно не вызовет такой метод.Это просто хорошая практика, похожая на get и set

 get onFilterShowSelected(): BehaviorSubject<any> {
        return this._onFilterShowSelected.asObservable();
    }
...