Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 and Jasmine unit testing: cannot get the innerHtml

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.

enter image description here

This is what it says : 'innerHTML' doesn't exist on type 'HTMLHeadingElement'

like image 925
Hussein Salman Avatar asked Oct 24 '16 21:10

Hussein Salman


1 Answers

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');
like image 101
Paul Samsotha Avatar answered Nov 26 '22 09:11

Paul Samsotha