I have an Angular (using Angular 10) component with a HTML snippet like below:
<div *ngIf="someCondition()" id="myID">
<p>Line 1</p>
<p>Line 2</p>
<p>Line 3</p>
<p>Line 4</p>
<p>Line 5</p>
<p>Line 6</p>
<p>Line 7</p>
</div>
Now, while unit testing, I would like to figure out if *ngIf
satisfies, the corresponding <div>
will have 7 child elements.
In the spec file, I have the following :
it('should check for 7 elements', async () => {
spyOn(component, 'someCondition()').and.returnValue(true);
fixture.detectChanges();
await fixture.whenRenderingDone();
const elements = fixture.debugElement.queryAllNodes(By.css('#myID'));
// const elements = fixture.debugElement.queryAll(By.css('#myID'));
console.log('check elements.... ', elements);
})
With the above, I can not get access to the child <p>
tags or the number of the children! Also, it would be good, if I could test a specific <p>
tag with expected value.
How can I achieve this?
CodePudding user response:
the first thing that I noticed it is SPY
it is not correct syntax: spyOn(component, 'someCondition()').and.returnValue(true);
should be spyOn(component, 'someCondition').and.returnValue(true);
- without function call
also in general I would use variable instaed of mehtod - it is easier to manipulate
Then you can do next
const resultArray = fixture.debugElement.queryAll(By.css('p'));
expect(resultArray[0].nativeElement.textContent.trim()).toBe('Line 1');
expect(resultArray[1].nativeElement.textContent.trim()).toBe('Line 2');
...
or you can check all values via loop
resultArray.forEach((el, i) =>
expect(el.nativeElement.textContent.trim()).toBe("Line " (i 1))
);
implementation via DIV
const div = fixture.debugElement.query(By.css("#myID"));
div.childNodes.forEach((el, i) =>
expect(el.nativeNode.innerText.trim()).toBe("Line " (i 1))
);
demo:
CodePudding user response:
Is your component using change detection ? You have to trigger change detection or override it in the testing module.
TestBed.configureTestingModule({
...declarations,
...providers
})
.overrideComponent(myComponent, {
set: { changeDetection: ChangeDetectionStrategy.Default }
})
.compileComponents();
To access childnodes , you can do :
beforeEach(() => {
fixture = TestBed.createComponent(LoginComponent);
component = fixture.componentInstance;
});
fixture.whenStable().then(
() => {
fixture.detectChanges();
var elementArray = fixture.debugElement. queryAll(By.css('#myID'));
expect(elementArray.length).toBeGreaterThan(0);
done();
}
);
To get children , you can also do this way
const items: DebugElement = fixture.debugElement.query(By.css('#myId'));
console.log(items.query(By.css('p')).children.map(e => e.nativeElement));
console.log(Array.from(items.query(By.css('p')).nativeElement.children));