在单元测试中,fixture.debugElement.nativeElement.query和document.getElement有什么区别?

jun*_*kie 3 html unit-testing jasmine karma-jasmine angular

我是 Angular 单元测试的新手,正在查看其他人编写的一些测试。我看到尝试以三种不同的方式访问元素:

  • fixture.debugElement.query(By.css('#hello'))
  • fixture.debugElement.nativeElement.querySelector('#hello')
  • document.getElementById('#hello')

使用这些有什么区别/最佳实践吗?

Sha*_*vek 5

对于HTML:

<div id="shan">Hey there</div>
Run Code Online (Sandbox Code Playgroud)
  1. Fixture.debugElement.query(By.css('#hello'))

它用于获取DOM 对象的“ DebugElement ”。更多信息可以在官方文档中找到。您可以传递idas By.css('#hello')classas By.css('.hello'),也可以使用By.css('div')或 等方式传递元素By.css('some-app-component')

DebugElement是一个 Angular 类,包含与调查元素组件相关的各种引用和方法

fixture.debugElement.query(By.css('#shan'))
Run Code Online (Sandbox Code Playgroud)

将返回

DebugElement__PRE_R3__{侦听器:[],父级:DebugElement__PRE_R3__{侦听器:[],父级:null,debugContext:DebugContext {view:...,nodeIndex:...,nodeDef:...,elDef:...,elView: ...},nativeNode:嘿,属性:Object{},属性:Object{ng-version:...},类:Object{},样式:Object{},childNodes:[...],nativeElement :嘿那里},debugContext:DebugContext {view:Object {def:...,parent:...,viewContainerParent:...,parentNodeDef:...,context:...,组件:...,节点:...,状态:...,根:...,渲染器:...,oldValues:...,一次性:...,initIndex:...},nodeIndex:0,nodeDef:对象{ nodeIndex:...,parent:...,renderParent:...,绑定索引:...,outputIndex:...,checkIndex:...,标志:...,childFlags:...,directChildFlags: ...,childMatchedQueries:...,matchedQueries:...,matchedQueryIds:...,引用:...,ngContentIndex:...,childCount:...,绑定:...,bindingFlags:.. .,输出:...,元素:...,提供者:...,文本:...,查询:...,ngContent:...},elDef:对象{nodeIndex:...,父级:...,renderParent:...,绑定索引:...,输出索引:...,检查索引:...,标志:...,childFlags:...,directChildFlags:...,childMatchedQueries:。 ..、matchedQueries:...、matchedQueryIds:...、引用:...、ngContentIndex:...、childCount:...、绑定:...、bindingFlags:...、输出:... ,元素:...,提供者:...,文本:...,查询:...,ngContent:...},elView:对象{def:...,父级:...,viewContainerParent: ...,parentNodeDef:...,上下文:...,组件:...,节点:...,状态:...,根:...,渲染器:...,oldValues:.. .,一次性:...,initIndex:...}},nativeNode:嘿,属性:Object{},属性:Object{id:'shan'},类:Object{},样式:Object{}, childNodes:[DebugNode__PRE_R3__{listeners: ..., Parent: ..., _debugContext: ..., ..nativeNode: ...}], nativeElement: 嘿,名称:'div'}


  1. Fixture.debugElement.nativeElement.querySelector('#hello')

nativeElement返回对 DOM 元素的引用,该元素也可以如上所述。您可以使用它执行测试用例中的事件debugElement等操作。click()

fixture.debugElement.nativeElement.querySelector('#hello').click(); // this will create a click event over this element.
Run Code Online (Sandbox Code Playgroud)

它适用于查询class 类似(fixture.debugElement.nativeElement.querySelector('.hello'))以及 之类的东西id

fixture.debugElement.nativeElement.querySelector('#shan')
Run Code Online (Sandbox Code Playgroud)

将返回

<div _ngcontent-a-c0="" id="shan">Hey there</div>
Run Code Online (Sandbox Code Playgroud)
  1. document.getElementById('你好')

这是我们访问 an id(而不是 a class)的好方法。您无法class通过执行类似的操作来访问

document.getElementById('.hello') // will return null
Run Code Online (Sandbox Code Playgroud)

另请注意,您不需要传入#此函数参数

document.getElementById('#hello') // will return null
Run Code Online (Sandbox Code Playgroud)

在使用时应避免使用它,angular因为 Angular 有其自己的特性ChangeDetection,需要使用它fixtures。通过直接调用document,您最终会用头撞墙,试图找出为什么该元素会出现null

document.getElementById('shan')
Run Code Online (Sandbox Code Playgroud)

将返回

<div _ngcontent-a-c0="" id="shan">Hey there</div>
Run Code Online (Sandbox Code Playgroud)

由于您是 Angular 单元测试的新手,因此可以参考我关于单元测试的系列文章。我希望这能帮到您。干杯!