Home > Enterprise >  How to test a ternary operator with Jest in Angular
How to test a ternary operator with Jest in Angular

Time:03-17

I have this code, and I want to test headerBackBtn with ternary operator this.headerBackBtnLabel ? true : false;.

@Component({
    selector: 'app-page-header',
    templateUrl: './page-header.component.html',
    styleUrls: ['./page-header.component.scss']
})
export class PageHeaderComponent {
    @Input() actions: IIcon[] = [];

    @Input() title!: string;

    @Input() headerBackBtnLabel = '';

    @Input() headerBackBtn = this.headerBackBtnLabel ? true : false; //◄◄◄

    @Output() actionClickName = new EventEmitter();

    actionClick(actionName: string): void {
        this.actionClickName.emit(actionName);
    }
}

I have this test ▼, but still test coverage shows that I am not covering ternary branch (see img)

    it('should render header back button element when there is BackBtnLabel', () => {
        component.headerBackBtnLabel = 'Any Button Label';
        component.headerBackBtn = Boolean(component.headerBackBtnLabel);
        fixture.detectChanges();
        const compiledElement = fixture.debugElement.query(
            By.css('.action-btn-label')
        );

        expect(component.headerBackBtn).toEqual(true);
        expect(compiledElement).toBeTruthy();
    });

enter image description here

How to fix this? I searched and tried a lot but still failing to solve :/

I can avoid branching by using @Input() headerBackBtn = Boolean(this.headerBackBtnLabel) but this is not a fix but just a workaround...

CodePudding user response:

I see 2 ways of doing this :

  1. Use the !! syntax in the html template

You want to replace the property with true if the value is non empty and false if the value is empty. The double negation syntax will do that.

  • The first negation will invert the value and cast it to a boolean.
  • The second negation will re-invert the value and keep it as a boolean
<div *ngIf="!!headerBackBtnLabel"> Display the button</div>
  1. Use the setter syntax on the input

Like this :

headerBackBtn: boolean
_headerBackBtnLabel: string

@Input() set headerBackBtnLabel(label: string) {
  this._headerBackBtnLabel = label;
  this.headerBackBtn = !!label;
}

CodePudding user response:

As @jonrsharpe and @Arnaud Denoyelle mentioned there were some issues with code. I've checked and I agree with @jonrsharpe "The true branch is unreachable". When @Input() headerBackBtnLabel is updated it doesn't not update @Input() headerBackBtn's default value, thus headerBackBtn stays false until not directly changed with true by its @Input.

  • Related