无法使用 Angular 单元测试访问 DIV 内的 child 节点
Can not access child nodes inside a DIV with Angular Unit Test
我有一个 Angular( 使用 Angular 10)组件,其中包含如下 HTML 片段:
<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>
现在,单元测试时,我想弄清楚*ngIf
是否满足,对应的<div>
将有7个child个元素。
在规格文件中,我有以下内容:
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);
})
通过上面的方法,我无法访问child <p>
标签或children 的号码!另外,如果我可以测试具有预期值的特定 <p>
标签,那就太好了。
我该如何实现?
我首先注意到它是 SPY
语法不正确:spyOn(component, 'someCondition()').and.returnValue(true);
应该是spyOn(component, 'someCondition').and.returnValue(true);
- 没有函数调用
一般来说,我会使用方法的变量 instaed - 它更容易操作
那你就可以做下一步了
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');
...
或者您可以通过循环检查所有值
resultArray.forEach((el, i) =>
expect(el.nativeElement.textContent.trim()).toBe("Line " + (i + 1))
);
通过 DIV
实施
const div = fixture.debugElement.query(By.css("#myID"));
div.childNodes.forEach((el, i) =>
expect(el.nativeNode.innerText.trim()).toBe("Line " + (i + 1))
);
演示:
https://codesandbox.io/s/adoring-khayyam-hygtd?file=/src/app/app.component.spec.ts
您的组件是否使用变更检测?您必须在测试模块中触发更改检测或覆盖它。
TestBed.configureTestingModule({
...declarations,
...providers
})
.overrideComponent(myComponent, {
set: { changeDetection: ChangeDetectionStrategy.Default }
})
.compileComponents();
要访问子节点,您可以这样做:
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();
}
);
要得到children,也可以这样
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));
我有一个 Angular( 使用 Angular 10)组件,其中包含如下 HTML 片段:
<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>
现在,单元测试时,我想弄清楚*ngIf
是否满足,对应的<div>
将有7个child个元素。
在规格文件中,我有以下内容:
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);
})
通过上面的方法,我无法访问child <p>
标签或children 的号码!另外,如果我可以测试具有预期值的特定 <p>
标签,那就太好了。
我该如何实现?
我首先注意到它是 SPY
语法不正确:spyOn(component, 'someCondition()').and.returnValue(true);
应该是spyOn(component, 'someCondition').and.returnValue(true);
- 没有函数调用
一般来说,我会使用方法的变量 instaed - 它更容易操作
那你就可以做下一步了
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');
...
或者您可以通过循环检查所有值
resultArray.forEach((el, i) =>
expect(el.nativeElement.textContent.trim()).toBe("Line " + (i + 1))
);
通过 DIV
实施
const div = fixture.debugElement.query(By.css("#myID"));
div.childNodes.forEach((el, i) =>
expect(el.nativeNode.innerText.trim()).toBe("Line " + (i + 1))
);
演示:
https://codesandbox.io/s/adoring-khayyam-hygtd?file=/src/app/app.component.spec.ts
您的组件是否使用变更检测?您必须在测试模块中触发更改检测或覆盖它。
TestBed.configureTestingModule({
...declarations,
...providers
})
.overrideComponent(myComponent, {
set: { changeDetection: ChangeDetectionStrategy.Default }
})
.compileComponents();
要访问子节点,您可以这样做:
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();
}
);
要得到children,也可以这样
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));