间谍行为主题并应用.pipe

时间:2019-07-06 13:31:55

标签: angular unit-testing jasmine observable karma-jasmine

当我尝试在我的服务上模拟行为类型为BehaviorSubject的一个属性时,我正在为我的组件运行单元测试,我收到此错误。 “ TypeError:无法读取未定义的属性'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 :(得分:0)

我将采用另一种方法,并创建一个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(); }

的好习惯
def func(foo):
    # type: (str) -> None
    bar = []  # type: List[str]
    bar.append(foo)