Home > database >  Component extends with super class needs help to test
Component extends with super class needs help to test

Time:11-16

Here is my base class:

export class DetailsComponent
extends AddClinicComponent
implements OnInit, AfterViewInit{}

in the spec of DetailsComponent.spec I am tryin to write a testing, which is in AddClinicComponent component.

here is the test:

fit('it should open popup  on click of button add clinic button ', async(() => {
    spyOn(component, 'openDialog');
    fixture.detectChanges();
    const removeButton =
        fixture.debugElement.nativeElement.querySelector('.hfs-add-btn');
    expect(removeButton).toBeTruthy();
    let event = new MouseEvent('click');
    removeButton.dispatchEvent(event);
    fixture.whenStable().then(() => {
        expect(component.openDialog).toHaveBeenCalled();
    });
}));

But getting an error as :

Error: Directive AddClinicComponent has no selector, please add it! how to resolve it? what is the correct way to test the extended component?

my super class:

import { TemplateRef, ViewChild } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { AddClinicDataService } from '../services/personnel-add-clinic-data.service';
import { HFSClinicTaleSchema } from './hfs-clinic-table.schema';
export abstract class AddClinicComponent {
    popTableSchema;
    clinicTaleSchema;
    @ViewChild('popupTemp', { static: true })
    popupTemp: TemplateRef<HTMLAllCollection>;
    public primaryName = '';
    public primaryAdminId = '';
    public dialog: MatDialog;

    constructor(protected aAddClinicDataService: AddClinicDataService) {
        this.clinicTaleSchema = HFSClinicTaleSchema;
    }

    clinicRowGenerator(rows) {
        return rows.map((p) => {
            return {
                ...p,
                address: Object.values(p.address).filter((v) => v != null),
                transform: true,
            };
        });
    }

    handleAddClinic() {
        this.popTableSchema = { ...HFSClinicTaleSchema, rows: [] };
        this.openDialog(this.popupTemp);
    }
    openDialog(templateRef: TemplateRef<HTMLAllCollection>) {
        const dialogRef = this.dialog.open(templateRef);
        dialogRef.afterClosed().subscribe((result) => {
            console.log(`Dialog result: ${result}`);
        });
    }

    addClinics() {
        const { rows } = this.popTableSchema;
        const transform = [...rows]
            .filter((r) => r.checked)
            .map((item) => ({ ...item, checked: false }));
        if (!transform.length) return;
        this.rowTransformer(transform);
        this.dialog.closeAll();
    }

    searchClinics($event: Event): void {
        $event.preventDefault();
        const formDetails = this.postProfile();
        const countryCodes = formDetails.countries.map((v) => v.codeId);
        const searchParams = {
            primaryAdminId: this.primaryAdminId,
            primaryName: this.primaryName,
            countryCodes: countryCodes.join(','),
        };
        this.fetchClinicList(
            `name=${this.primaryName}&adminUserName=${
                this.primaryAdminId
            }&countryCds=${countryCodes.join(',')}`
        );
        this.primaryAdminId = '';
        this.primaryName = '';
    }
    fetchClinicList(searchParams) {
        this.aAddClinicDataService
            .getClinicsList(searchParams)
            .subscribe((data) => {
                const nwRows = data?.map((d) => {
                    return {
                        ...d,
                        address: Object.values(d.address).filter(
                            (v) => v !== null
                        ),
                    };
                });
                this.popTableSchema = { ...this.popTableSchema, rows: nwRows };
            });
    }
    protected abstract rowTransformer(value);
    abstract postProfile();
}

after having some try: I got this error:

 Error: This constructor is not compatible with Angular Dependency Injection because its dependency at index 0 of the parameter list is invalid.
        This can happen if the dependency type is a primitive like a string or if an ancestor of this class is missing an Angular decorator.

        Please check that 1) the type for the parameter at index 0 is correct and 2) the correct Angular decorators are defined for this class and its ancestors.

constructor of details component:

constructor(
        private personnelViewDataService: PersonnelViewDataService,
        private personnelTranslateService: PersonnelTranslateService,
        private cdr: ChangeDetectorRef,
        public dialog: MatDialog,
        protected aAddClinicDataService: AddClinicDataService
    ) {
        super();
    }

constructor of AddClinicComponent

 constructor(protected aAddClinicDataService: AddClinicDataService) {
        this.clinicTaleSchema = HFSClinicTaleSchema;
    }

CodePudding user response:

Dependency injection works only if the class has an Angular decorator.

DI is wired into the Angular framework and allows classes with Angular decorators, such as Components, Directives, Pipes, and Injectables, to configure dependencies that they need.

https://angular.io/guide/dependency-injection

This could be causing the error, try to inject the service in the component class and when calling super pass the service to the extended class

constructor of details component:

constructor(
  private personnelViewDataService: PersonnelViewDataService,
  private personnelTranslateService: PersonnelTranslateService,
  private cdr: ChangeDetectorRef,
  public dialog: MatDialog,
  public aAddClinicDataService: AddClinicDataService
) {
  super(aAddClinicDataService);
}
  • Related