问题描述
我为使用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
类(而且我也不想这么做!),我希望它的内容能够正确呈现。是因为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);
编辑:我不完全确定该指令的类名是什么(也许是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;
});