How to test <ng-content> in angular 2

3,925 views
Skip to first unread message

Jonatan Nuñez

unread,
Oct 27, 2016, 4:01:47 AM10/27/16
to Angular
Hi,

How can I test that my component is transcluding the content?

For example:

import {Component, Input} from '@angular/core';

@Component({
    selector
: 'my-com',
   
template: `
        <div>
            <h1 class="title">{title}</h1>
            <div class="content">
                <ng-content></ng-content>
            </div>
        </div>
    `

})
export class MyComponent {
   
@Input() title: string = '';
}

I need to test that MyComponent is binding the title and transcluding the content:

import { ComponentFixture, TestBed} from '@angular/core/testing';
import { By }              from '@angular/platform-browser';
import { DebugElement }    from '@angular/core';

import { MyComponent } from 'path/to/mycomponent';

let comp
:    MyComponent;
let fixture
: ComponentFixture<MyComponent>;

describe
('MyComponent', () => {

    beforeEach
(() => {
       
TestBed.configureTestingModule({
            declarations
: [ MyComponent ]
       
});

        fixture
= TestBed.createComponent(MyComponent);

        comp
= fixture.componentInstance;
        fixture
.detectChanges();
   
});

    it
('should create the component', () => {
        expect
(comp).toBeTruthy();
   
});

    it
('should bind the title', () => {
        let de
: DebugElement = fixture.debugElement.query(By.css('.title'));
        let el
: HTMLElement = de.nativeElement;

       
const myTitle: string = 'myTitle';
        comp
.title = myTitle;

        fixture
.detectChanges();

        expect
(el.textContent).toBe(myTitle);
   
});
});

Now, how can I set the content to my component?

it('should transclude the content', () => {
    let de
: DebugElement = fixture.debugElement.query(By.css('.content'));
    let el
: HTMLElement = de.nativeElement;

   
const myContent: string = '<div id="test"></div>';
    comp
.CONTENT = myContent; //how to set content ¿?

    fixture
.detectChanges();

    expect
(el.children[0].id).toBe('test');
});

In angular 1, I think we need to do a custom $compile. Something like:

$compile('<my-com><div id="test"></div></my-com>')(scope);

Thanks!

Yann Vo

unread,
Sep 25, 2017, 9:42:36 PM9/25/17
to Angular and AngularJS discussion
Hi,

In case you are still looking for an answer, you have to revert to a test host component

In your test, you create a dummy component holding the one you want to test (my-com):
@Component({
    template: `<my-com title="foo">Hello world</my-com>`
})
class TestHostComponent {
}

Then you can follow the directions on the link to the doc provided above to:
1) inject that test host component as well as the component under test (MyComponent).
2) call fixture = TestBed.createComponent(TestHostComponent);
3) use CSS queries to get back to what you'd like to test

Hope this helps


Reply all
Reply to author
Forward
0 new messages