Reputation: 1833
I have an Angular 6 app and writing some unit tests trying to determine if an element is visible or not based solely on the boolean result of an *ngIf
directive.
Markup:
<div class="header" *ngIf="show">
<div>...</div>
</div>
spec file:
it('should hide contents if show is false', () => {
const button = debugElement.query(By.css('button')).nativeElement;
button.click(); // this will change show to false
fixture.detectChanges();
expect(debugElement.query(By.css('.header')).nativeElement.style.hidden).toBe(true);
});
I can't seem to get the hidden
attribute from the div. Does angular use another approach to hiding the element from the DOM using the *ngIf
directive? Do I need to get another property from the nativeElement
?
Thanks!
Upvotes: 45
Views: 99873
Reputation: 171
You need add fixture.detectChanges() after you change value of 'show' to true
component.show = true;
fixture.detectChanges()
Upvotes: 12
Reputation: 29715
If the element is hidden, then it wont be rendered inside the dom.
You can check
expect(fixture.debugElement.query(By.css('.header'))).toBeUndefined();
EDIT : toBeNull()
works better in the above case
expect(fixture.debugElement.query(By.css('.header'))).toBeNull();
And also you have a syntax error while fetching the button element. nativeElement
is not a function.
Change it this way :
const button = fixture.debugElement.query(By.css('button')).nativeElement;
Upvotes: 63
Reputation: 51
Writing test case for *ngIf
condition use toBeNull
condition.
Try with below code, it works for me.
expect(fixture.debugElement.query(By.css('.header'))).toBeNull();
Upvotes: 4
Reputation: 14958
When testing if a component is being shown or not using ngIf
I try to get the element (in this case you use, i.e., debugElement.query(By.css('.header')).nativeElement
) and if it should be shown I expect it to be truthy, otherwise falsy.
Something like this:
it('should hide contents if show is false', () => {
// should be rendered initially
expect(debugElement.query(By.css('.header')).nativeElement).toBeTruthy();
//trigger change
const button = debugElement.query(By.css('button')).nativeElement;
button.click(); // this will change show to false
fixture.detectChanges();
// should not be rendered
expect(debugElement.query(By.css('.header')).nativeElement).toBeFalsy();
});
Also, bear in mind that sometimes you need to use ComponentFixture#whenStable
to detect when the fixture is stable like this:
it('should hide contents if show is false', () => {
const fixture = TestBed.createComponent(AppComponent);
fixture.whenStable().then(() => {
// same test code here
});
});
See this working test for a component which resembles this scenario.
See [GitHub repository]
Upvotes: 13
Reputation: 5988
When using ngIf, angular completely removes the node from markup. So you need to check that this element not exists.
ngIf evaluates the expression and then renders the then or else template in its place when expression is truthy or falsy respectively.
To be more precise, it's just not rendered
Upvotes: 3