'Unit test for Button with disable
I am trying to write a unit test for a button that has disabled assigned to a boolean.
html looks like:
<button *ngIf="!data" id="createBtn" mat-button color="primary" (click)="submitNewCase()" [disabled]="disableCreate">{{ 'ACTIONS.create' | translate }}</button>
my unit test:
beforeEach(() => {
fixture = TestBed.createComponent(CaseComponent);
component = fixture.componentInstance;
fixture.detectChanges();
submitEl = fixture.debugElement.query(By.css('button'));
});
it('DisableCreate set to true disables the submit button', () => {
component.disableCreate = true;
fixture.detectChanges();
expect(submitEl.nativeElement.disabled).toBeTruthy();
});
it('DisableCreate set to false enables the submit button', () => {
component.disableCreate = false;
fixture.detectChanges();
expect(submitEl.nativeElement.disabled).toBeFalsy();
});
My second unit test succeeds and my first one does not. I am getting back a "Expected false to be truthy.". I cannot find where this is failing and why.
Any help would be much appreciated.
Solution 1:[1]
So after banging my head against the table a little longer it looks like I was selecting the button incorrectly. Using querySelector for button has my test succeeding. Also to @Fateh Mohamed's comment setting component.data to null is required since there is a ngIf for data on the button.
beforeEach(() => {
fixture = TestBed.createComponent(CaseComponent);
component = fixture.componentInstance;
fixture.detectChanges();
submitEl = fixture.debugElement
});
it('DisableCreate set to true disables the submit button', () => {
component.disableCreate = true;
component.data = null;
fixture.detectChanges();
expect(submitEl.nativeElement.querySelector('button').disabled).toBeTruthy();
});
it('DisableCreate set to false enables the submit button', () => {
component.disableCreate = false;
component.data = null;
fixture.detectChanges();
expect(submitEl.nativeElement.querySelector('button').disabled).toBeFalsy();
});
Solution 2:[2]
Found another way,
in your HTML add id to button, i.e
<button id="myButtonId" [disabled]="someCondition">/<button>
in test file get the button (by id or any other way) and check disabled state by ng-reflect-disabled attribute
const addButton = fixture.debugElement.nativeElement.querySelector('#myButtonId');
expect(addButton.attributes.getNamedItem('ng-reflect-disabled').value).toBeTruthy();
Solution 3:[3]
None of the answers worked for me on Angular 11 so leaving my 2 cents here:
Template:
<div class="actions">
<button [disabled]="loading">
Submit
</button>
</div>
Class (simplified):
export class SubmitComponent {
loading = false;
}
Test:
import { By } from '@angular/platform-browser';
...
let component: SubmitComponent;
let fixture: ComponentFixture<SubmitComponent>;
beforeEach(() => {
fixture = TestBed.createComponent(SubmitComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should disable on load', () => {
fixture.componentInstance.loading = true;
fixture.detectChanges();
const button: HTMLButtonElement = fixture.debugElement.query(By.css('.actions > button')).nativeElement;
expect(button.attributes.getNamedItem('ng-reflect-is-disabled')?.value).toEqual('true');
// or
expect(button.attributes.getNamedItem('ng-reflect-is-disabled')?.value).toBeTruthy();
});
Solution 4:[4]
import { By } from '@angular/platform-browser';
...
let component: SubmitComponent;
let fixture: ComponentFixture<SubmitComponent>;
beforeEach(() => {
fixture = TestBed.createComponent(SubmitComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should disable on load', () => {
fixture.componentInstance.loading = true;
fixture.detectChanges();
const buttons= fixture.nativeElement.querySelectorAll(
'.actions > button'
);
buttons.forEach(button => {
expect(button.attributes['disabled'].value).toEqual('true');
});
// or in false case .
buttons.forEach(button => {
expect(button.attributes['disabled']).toBeUndefined();
});
});
Solution 5:[5]
If anyone is using the @ngneat/spectator package and testing values declared as @Input(), use spectator.setInput({ myInputValue: true })
instead of component.myInputValue = true;
in your tests.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Liam |
Solution 2 | Liam |
Solution 3 | Erwol |
Solution 4 | hrushikesh das |
Solution 5 | Jan Nicklas |