Angular2 测试:ComponentFixture 中的 DebugElement 和 NativeElement 对象有啥区别?

Posted

技术标签:

【中文标题】Angular2 测试:ComponentFixture 中的 DebugElement 和 NativeElement 对象有啥区别?【英文标题】:Angular2 testing: What's the difference between a DebugElement and a NativeElement object in a ComponentFixture?Angular2 测试:ComponentFixture 中的 DebugElement 和 NativeElement 对象有什么区别? 【发布时间】:2016-10-08 21:42:43 【问题描述】:

我目前正在整理一些在组件级别测试 Angular 2 应用程序的最佳实践。

我看过一些教程查询夹具的 NativeElement 对象以获取选择器等,例如

it('should render "Hello World!" after click', async(() => 
    builder.createAsync(HelloWorld).then((fixture: ComponentFixture<HelloWorld>) => 
        fixture.detectChanges();
        let el = fixture.nativeElement;
        el.querySelector('h1').click();
        fixture.detectChanges();
            
        expect(el.querySelector('h1')).toHaveText('Hello World!');
    );
));

但是,在juliemr's Angular 2 test seed 中,她通过父 DebugElement 对象访问 NativeElement。

it('should render "Hello World!" after click', async(() => 
    builder.createAsync(HelloWorld).then((fixture: ComponentFixture<HelloWorld>) => 
      fixture.detectChanges();
      let compiled = fixture.debugElement.nativeElement;
      compiled.querySelector('h1').click();
      fixture.detectChanges();
            
      expect(compiled.querySelector('h1')).toHaveText('Hello World!');
    );
));

是否有任何特定情况下您会使用夹具的 debugElement.nativeElement 而不是其 nativeElement?

【问题讨论】:

【参考方案1】:

看看Angular discussion about this topic和相关的PR。

主要是:

fixture.componentInstance == fixture.debugElement.componentInstance;
fixture.nativeElement == fixture.debugElement.nativeElement;

【讨论】:

干杯,非常有帮助。【参考方案2】: nativeElement 返回对 DOM 元素的引用 DebugElement 是一个 Angular2 类,它包含与调查元素或组件相关的各种引用和方法(参见 source of DebugNode and DebugElement

【讨论】:

干杯 - 所以我想如果我没有使用除 nativeElement 之外的任何 DebugElement 成员,那么使用 componentFixture.nativeElement 可能更具可读性。 nativeElement 仅在您想要调查 DOM(属性、类、...设置或清除或可能调度 DOM 事件)时为您提供帮助。当您想调查 Angular2 应用程序(组件、指令等)的各个部分的状态时,您需要 DebugElement【参考方案3】:

补充已经提到的内容:

  abstract class ComponentFixture 
  debugElement;       // test helper 
  componentInstance;  // access properties and methods
  nativeElement;      // access DOM
  detectChanges();    // trigger component change detection

来源:https://github.com/angular/angular/blob/a7e9bc97f6a19a2b47b962bd021cb91346a44baa/modules/angular2/src/testing/test_component_builder.ts#L31

【讨论】:

【参考方案4】:

.nativeElement() 返回 DOM 树,而 debugElement 返回一个 JS 对象(debugElement 树)。 debugElement 是 Angular 的方法。

.nativeElement() 是浏览器特定的 API,它返回或授予对 DOM 树的访问权限。但是如果应用程序运行在非浏览器平台(例如服务器或 web-worker)上,那么.nativeElement() 可能会抛出错误。

如果我们确定我们的应用程序只能在浏览器上运行,那么 我们可以毫不犹豫地使用let el = fixture.nativeElement。但是如果我们 不确定平台是否更安全,请使用let le = fixture.debugElement,因为它返回一个普通的 JS 对象。

【讨论】:

以上是关于Angular2 测试:ComponentFixture 中的 DebugElement 和 NativeElement 对象有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

通过 Webpack(终端)执行 Typescript Jasmine 测试以测试 Angular2

angular2 使用主机组件进行单元测试

Angular2 - 在组件中测试 ngOninit

Angular2 - 在测试中模拟 RouteParams

Angular2 - 使用 debounceTime 测试调用

如何为 angular2 的登录组件编写测试(单元测试)