Angular 2 and Jasmine unit testing: cannot get the innerHtml
It's because content
const content = el.querySelector('h3');
expect(content).toContain('Bubba');
is the HTMLNode
, not the raw text. So you're expecting an HTMLNode
to be a string. This will fail.
You need to extract the raw HTML either with content.innerHTML
or content.textContent
(to just get content between the <h3>
tags
const content = el.querySelector('h3');
expect(content.innerHTML).toContain('Bubba');
expect(content.textContent).toContain('Bubba');
Related videos on Youtube
Hussein Salman
Engineering Manager & Cloud-Native Architect, focusing on Kubernetes, Containers & Microservices. Check out my youtube channel: https://www.youtube.com/channel/UCoAh8g6dmwXQUwKhkggUFIA
Updated on July 05, 2022Comments
-
Hussein Salman over 1 year
I am using one of the examples that test a component 'WelcomeComponent':
import { Component, OnInit } from '@angular/core'; import { UserService } from './model/user.service'; @Component({ selector: 'app-welcome', template: '<h3>{{welcome}}</h3>' }) export class WelcomeComponent implements OnInit { welcome = '-- not initialized yet --'; constructor(private userService: UserService) { } ngOnInit(): void { this.welcome = this.userService.isLoggedIn ? 'Welcome ' + this.userService.user.name : 'Please log in.'; } }
This is the test case, i am checking if the 'h3' contains the user name 'Bubba':
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { DebugElement } from '@angular/core'; import { UserService } from './model/user.service'; import { WelcomeComponent } from './welcome.component'; describe('WelcomeComponent', () => { let comp: WelcomeComponent; let fixture: ComponentFixture<WelcomeComponent>; let componentUserService: UserService; // the actually injected service let userService: UserService; // the TestBed injected service let de: DebugElement; // the DebugElement with the welcome message let el: HTMLElement; // the DOM element with the welcome message let userServiceStub: { isLoggedIn: boolean; user: { name: string } }; beforeEach(() => { // stub UserService for test purposes userServiceStub = { isLoggedIn: true, user: { name: 'Test User' } }; TestBed.configureTestingModule({ declarations: [WelcomeComponent], // providers: [ UserService ] // NO! Don't provide the real service! // Provide a test-double instead providers: [{ provide: UserService, useValue: userServiceStub }] }); fixture = TestBed.createComponent(WelcomeComponent); comp = fixture.componentInstance; // UserService actually injected into the component userService = fixture.debugElement.injector.get(UserService); componentUserService = userService; // UserService from the root injector userService = TestBed.get(UserService); // get the "welcome" element by CSS selector (e.g., by class name) el = fixture.debugElement.nativeElement; // de.nativeElement; }); it('should welcome "Bubba"', () => { userService.user.name = 'Bubba'; // welcome message hasn't been shown yet fixture.detectChanges(); const content = el.querySelector('h3'); expect(content).toContain('Bubba'); }); });
When Testing and debugging the test case using Karma, If i evaluate "el.querySelector('h3') in the console it shows the following
<h3>Welcome Bubba</h3>
How, i can get the innerHtml of the heading, since it doesn't resolve when including it in the ts file and the test case evaluates to false always.
This is what it says : 'innerHTML' doesn't exist on type 'HTMLHeadingElement'
-
Hussein Salman over 7 yearsThanks @peeskillet for clarifying that. I added more details to my question. I know that it is missing property innerHTML that should be called, but it cannot be resolved, Am I missing anything?
-
Paul Samsotha over 7 yearsDo you get a runtime error? Or is it just an error in the IDE? I tested it and it works fine for me
-
Hussein Salman over 7 yearsI run it, its working. I thought that it will run since the IDE didn't resolve it. Do you know how to fix this issue?
-
Paul Samsotha over 7 yearsI don't know how to "fix" it because I can't reproduce it in my environment. But to work around it, you can do
(<any>content).innerHTML
-
t.j. almost 6 years@Coding - re: missing prop -->
const content = el.querySelector('h3') as HTMLElement;
content
now has.innerHTML