Angular2 testing: What's the difference between a DebugElement and a NativeElement object in a ComponentFixture?
I'm currently putting together some best practices for testing Angular 2 apps on a component level.
I've seen a few tutorials query a fixture's NativeElement object for selectors and the like, e.g.
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!');
});
}));
However, in juliemr's Angular 2 test seed she accesses the NativeElement through a parent DebugElement object.
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!');
});
}));
Are there any specific cases you'd use a fixture's debugElement.nativeElement over its nativeElement?
Solution 1:
-
nativeElement
returns a reference to the DOM element -
DebugElement
is an Angular2 class that contains all kinds of references and methods relevant to investigate an element or component (See the source of DebugNode and DebugElement
Solution 2:
to add on to what has been mentioned already :
abstract class ComponentFixture {
debugElement; // test helper
componentInstance; // access properties and methods
nativeElement; // access DOM
detectChanges(); // trigger component change detection
}
source: https://github.com/angular/angular/blob/a7e9bc97f6a19a2b47b962bd021cb91346a44baa/modules/angular2/src/testing/test_component_builder.ts#L31
Solution 3:
Take a look at Angular discussion about this topic and related PR.
Mainly:
fixture.componentInstance == fixture.debugElement.componentInstance;
fixture.nativeElement == fixture.debugElement.nativeElement;
Solution 4:
.nativeElement()
returns DOM tree whereas debugElement
returns a JS object (debugElement tree). debugElement
is a Angular's method.
.nativeElement()
is Browser specific API that returns or give access to DOM tree. But what if application is running on non-browser platform (such as server or web-worker), in that case .nativeElement()
may throw error.
If we are sure that our application will run on browser only, then unhesitantly we can use
let el = fixture.nativeElement
. But if we are not sure about the platform then to be on safer side uselet le = fixture.debugElement
because it returns a plain JS Object.