Angular 测试:在使用 ng-content 的子组件中获取 HTML 元素
Angular Testing: Get HTML Element inside child component that uses ng-content
我在为使用 ngb-accordion 显示其内容的组件编写单元测试时遇到问题。在这种情况下,手风琴仅用于样式目的,但我用它来提供整个应用程序的设计一致性。
我能想到的最简单的错误显示模板:
<ngb-accordion #acc="ngbAccordion" activeIds="sample">
<ngb-panel id="sample">
<ng-template ngbPanelContent>
<p class="myClass">Some Text</p> <!-- I want to access this element -->
</ng-template>
</ngb-panel>
</ngb-accordion>
测试用例如下所示:
it('should find my element', () => {
fixture = TestBed.createComponent(LoginComponent);
component = fixture.componentInstance;
fixture.detectChanges();
const p = fixture.debugElement.query(By.css('.myClass')).nativeElement;
p.id;
});
这会引发错误:
TypeError: Cannot read property 'nativeElement' of null
这是我测试的beforeEach
:
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ LoginComponent, NgbAccordion ],
providers : [FormBuilder, ...]
})
.compileComponents();
}));
(其中 LoginComponent
是被测试的组件)。
我觉得跟ng-template
没有关系,如下html,元素找对了:
<div *ngIf="false else always">Should not show</div>
<ng-template #always>
<p class="myClass">Some Text</p>
</ng-template>
我不知道为什么它不适用于 ngbAccordion
,会不会是时间问题?因为我不是在嘲笑 NgbAccordion
class(而且我不想!),所以我希望它的内容能够正确呈现。是吗,因为 html 可能是在 'NgbAccordion' 中用 'ng-content' 渲染的?如果是这样,我该怎么做才能访问我的元素?
非常感谢任何帮助。
当它在像这样的外来元素中时,我有时也会遇到这种情况。
而不是 query
尝试直接进入 nativeElement
或使用 document.querySelector
.
const p = fixture.nativeElement.querySelector('.myClass');
console.log(p); // see if it returns
const p2 = document.querySelector('.myClass');
console.log(p2); // see if it returns
如果这不起作用,请检查 nativeElement
并确保元素在那里;
const nativeElement = fixture.nativeElement;
console.log(nativeElement);
编辑:我不完全确定指令的 class 名称是什么(可能是 NgBPanelContent),但请确保将其包含在声明数组中,以便 HTML 知道如何绘制它它看到了那个指令。
我想你需要等待渲染;
// async added here
it('should find my element', async () => {
fixture = TestBed.createComponent(LoginComponent);
component = fixture.componentInstance;
fixture.detectChanges();
// and await rendering
await fixture.whenRenderingDone();
const p = fixture.debugElement.query(By.css('.myClass')).nativeElement;
p.id;
});
我在为使用 ngb-accordion 显示其内容的组件编写单元测试时遇到问题。在这种情况下,手风琴仅用于样式目的,但我用它来提供整个应用程序的设计一致性。
我能想到的最简单的错误显示模板:
<ngb-accordion #acc="ngbAccordion" activeIds="sample">
<ngb-panel id="sample">
<ng-template ngbPanelContent>
<p class="myClass">Some Text</p> <!-- I want to access this element -->
</ng-template>
</ngb-panel>
</ngb-accordion>
测试用例如下所示:
it('should find my element', () => {
fixture = TestBed.createComponent(LoginComponent);
component = fixture.componentInstance;
fixture.detectChanges();
const p = fixture.debugElement.query(By.css('.myClass')).nativeElement;
p.id;
});
这会引发错误:
TypeError: Cannot read property 'nativeElement' of null
这是我测试的beforeEach
:
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ LoginComponent, NgbAccordion ],
providers : [FormBuilder, ...]
})
.compileComponents();
}));
(其中 LoginComponent
是被测试的组件)。
我觉得跟ng-template
没有关系,如下html,元素找对了:
<div *ngIf="false else always">Should not show</div>
<ng-template #always>
<p class="myClass">Some Text</p>
</ng-template>
我不知道为什么它不适用于 ngbAccordion
,会不会是时间问题?因为我不是在嘲笑 NgbAccordion
class(而且我不想!),所以我希望它的内容能够正确呈现。是吗,因为 html 可能是在 'NgbAccordion' 中用 'ng-content' 渲染的?如果是这样,我该怎么做才能访问我的元素?
非常感谢任何帮助。
当它在像这样的外来元素中时,我有时也会遇到这种情况。
而不是 query
尝试直接进入 nativeElement
或使用 document.querySelector
.
const p = fixture.nativeElement.querySelector('.myClass');
console.log(p); // see if it returns
const p2 = document.querySelector('.myClass');
console.log(p2); // see if it returns
如果这不起作用,请检查 nativeElement
并确保元素在那里;
const nativeElement = fixture.nativeElement;
console.log(nativeElement);
编辑:我不完全确定指令的 class 名称是什么(可能是 NgBPanelContent),但请确保将其包含在声明数组中,以便 HTML 知道如何绘制它它看到了那个指令。
我想你需要等待渲染;
// async added here
it('should find my element', async () => {
fixture = TestBed.createComponent(LoginComponent);
component = fixture.componentInstance;
fixture.detectChanges();
// and await rendering
await fixture.whenRenderingDone();
const p = fixture.debugElement.query(By.css('.myClass')).nativeElement;
p.id;
});