Search code examples
angularangular-test

How to make coverage with internal observable method in testing


here is the component methods:

resetPage(): void {
        this.deletedClinicPosProps = { appId: [] };
        this.addedClinicPosProps = { appId: [] };
        this.resetHeaders();
        this.canSaveEnabled = { a: false, b: false, c: false };
        this.profileForm.hfsForm.reset();
        this.isDataSaved = false;
        this.setPage();
    }

and another method which calls the above method on post:

postClinicUpdate() {
        this.postProfile();
        if (!this.profileForm.isHfsFormIsValid) {
            return;
        }
        const {
            slide,
            timezone: { codeId },
        } = this.profileFormValue;
        const { sjmAccDTO } = this.userProfile;
        const sjmAccountId = sjmAccDTO.sjmAccountId;

        const postData: UpdateClinicProps = {
            sjmAccountId: sjmAccountId,
            hfsStatus: slide === true ? 1 : 0,
            timeZoneCd: codeId,
            addedClinicIds: this.addedClinicPosProps.appId,
            deletedClinicIds: this.deletedClinicPosProps.appId,
            deletedCountryCds:
                this.profileForm.countrySelectionProps.removedCountries,
            addedCountryCds:
                this.profileForm.countrySelectionProps.addedCountries,
        };
        this.personnelViewDataService
            .updateClinics(postData)
            .subscribe((updates) => {
                if (updates) {
                    this.resetPage();
                    this.actOfSaveEnabled = false;
                    this._location.back();
                }
            });
    }

mock service for testing:

const mockPersonnelViewDataService = {
        userProfileWithCodes$: of(testMockData),
        fetchUserProfileWithCode: function () {
            return this.userProfileWithCodes$;
        },
        updateClinics: function () {
            return { subscribe: () => {} };
        },
        responseUpdateClinic$: of({}),
    };

testing:

it('should call postClinicUpdate to save data, and rest the page', fakeAsync(() => {
        const updateClinics = spyOn(service, 'updateClinics').and.callThrough();
        const postClinicUpdate = spyOn(
            component,
            'postClinicUpdate'
        ).and.callThrough();
        const resetPage = spyOn(component, 'resetPage').and.callThrough();
        const btnRemoveClinic = fixture.debugElement.query(
            By.css('#btn-removeClinic')
        ).nativeElement;
        const btnPostClinic = fixture.debugElement.query(
            By.css('#btn-postClinic')
        ).nativeElement;
        profileTable = fixture.debugElement.query(By.css('table#details-view'));
        const checkBox: HTMLInputElement = profileTable.query(
            By.css('tbody input[type=checkbox]')
        ).nativeElement;

        checkBox.click();
        tick(1000);

        btnRemoveClinic.click();
        tick(1000);
        btnPostClinic.click();
        expect(postClinicUpdate).toHaveBeenCalled();
        tick(1000);
        component.resetPage();
        expect(resetPage).toHaveBeenCalled();
    }));

no error thrown. all are success. But my resetPage() method not under the test coverage. still it show under uncover part. How to make my resetPage come under coverage with current testing?

what I missed or what change need i do? thanks in advance


Solution

    • You are directly calling component.resetPage(); that is probably why the test case is passing.
    • updateClinics returns an object not an observable

    Remove component.resetPage() and add return of('test') to the mock

    const mockPersonnelViewDataService = {
      updateClinics: function () {
        return of('test');
      },
    
     ...
    };