无法使用 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));