mardi 8 octobre 2019

Broken component after fixture.detectChanges() in Angular 2

I'm having problem testing a really basic angular component. In particular it looks like that after changing some properties and applying fixture.detectChange the fixture.debugElement.nativeElement does not contain anymore the right value.

Here is the HTML template:

<p-overlayPanel [appendTo]="'body'" class="inv select-overlay checkbox" #mOverlay>
<div class="over-c">
    <h3 class="title">TITLE</h3>
    <div class="overflow">
        <div *ngIf="loading">
            <i class="fa loading"></i>
        </div>
        <div *ngIf="!loading">
            <div class="ui-g-12 ui-g-nopad" *ngFor="let item of items">
                <p-radioButton class="align-select" name="check" [label]="item.description.title"
                    [value]="{name: item.description.title, id: item.id}" [(ngModel)]="selected" data-testid="checkbox-invite">
                </p-radioButton>
            </div>
        </div>
    </div>
    <div class="ui-g column-filters">
        <button type="button" (click)="onAdd($event)" pButton label="LINK"
            data-testid="invite"></button>
    </div>
</div>
</p-overlayPanel>

Here is the component:

export class Component {
@Output() onComplete = new EventEmitter<any>();
@ViewChild('mOverlay') overlay: any;

public items: any[] = [];
public selected: any;
public loading: boolean;
private subscriptions: Subscription[] = [];

constructor(
    private mService: MService,
    public translate: TranslateService,
) { }

ngOnDestroy() {
    this.subscriptions.forEach((subscription) => {
        subscription.unsubscribe();
    })
}

public refreshM(uId, brId) {
    this.loading = true;
    this.items = null;
    this.subscriptions.push(this.mService.getUserM(uId, bId).subscribe(result => {
        this.items = result;
        this.loading = false;
    }));
}

public onAdd(event) {
    if (this.selected) {
        this.overlay.hide(event);
        this.onComplete.emit(this.selected);
    }
}

public toggle(event) {
    this.overlay.toggle(event);
}
}

As you can see it's a really simple component (a bit censured but that's the main logic).

Here are the tests i try to run:

describe("Component", () => {
beforeEach(() => {
    TestBed.configureTestingModule({
        declarations,
        providers,
        imports
    })
    fixture = TestBed.createComponent(Component);
    component = fixture.componentInstance;
});

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

it("should have an invite button", () => {
    const button = fixture.debugElement.nativeElement.querySelector("[data-testid='invite']")
    expect(button).toBeTruthy()
})

it("should have an invite button even if loading", () => {
    component.missionsLoading = true
    fixture.detectChanges();

    const button = fixture.debugElement.nativeElement.querySelector("[data-testid='invite']")
    expect(button).toBeTruthy()
})

As you can see this are pretty basic tests, however i don't know why the third one keeps failing. It looks like it's a problem related to fixture.detectChanges() because after some investigation i've found that before its execution fixture.debugElement.nativeElement looks like:

<div id="root2" ng-version="2.4.6"><p-overlaypanel class="inviteToMissionPanel select-columns-overlay custom-blue-checkbox">
        <div>
            <div class="ui-overlaypanel-content">

    <div class="overlay-content">
        <h3 class="select-columns-title" />
        <div class="ui-g overflow">
            <!--template bindings={}-->
            <!--template bindings={}-->
        </div>
        <div class="ui-g column-filters">
            <button data-testid="invite-button" pbutton="" type="button" />
        </div>
    </div>

            </div>
            <!--template bindings={}-->
        </div>
    </p-overlaypanel></div>

however after that instruction setting the component loading property to true and applying fixture.detectChanges() it looks like:

<div id="root2" ng-version="2.4.6"><p-overlaypanel class="inviteToMissionPanel select-columns-overlay custom-blue-checkbox" ng-reflect-append-to="body">

    </p-overlaypanel></div>

I would really appreciate if any of you could help me understand what i'm doing wrong here.

P.s. to debug the tests and print the value fixture.debugElement.nativeElement i'm placing expect(fixture.debugElement.nativeElement).toBeFalsy() which makes the tests fail and notify me of the "Received" value, i hope it's fine.

Aucun commentaire:

Enregistrer un commentaire