Karma showing this error TypeError: Cannot read property 'textContent' of undefinedAngular2 NgModel not getting value in Jasmine testKarma-Jasmine TypeError: this.ngRedux.getState is not a functionkarma TypeError “Cannot read property 'subscribe' of undefined”Karma: Cannot read property * of undefinedError karma on watch => ERROR in TypeError: Cannot read property 'length' of undefinedJasmine / karma error as cannot read property of undefinedUncaught TypeError: Cannot read property 'length' of undefined - Jasmine/Karma Angualr2TypeError: Cannot read property 'fetchData' of undefined jasmine-karmaTypeerror cannot read property 'triggereventhandler' of undefined in Karma-Jasmine testing
Do Milankovitch Cycles fully explain climate change?
How to work with a technician hired with a grant who argues everything
How do I politely hint customers to leave my store, without pretending to need leave store myself?
Have there been any countries that voted themselves out of existence?
How could a imperial dynasty keep a loose collection of pirates, raiders, etc unified?
Creating a Master Image to roll out to 30 new Machines Licensing Issues
Can a magnet rip protons from a nucleus?
Should I leave the first authourship of our paper to the student who did the project whereas I solved it?
Were Roman public roads build by private companies?
Why do sellers care about down payments?
Why did they ever make smaller than full-frame sensors?
Who are the two thieves that appear the opening of Batman: TAS?
Is it appropriate for a professor to require students to sign a non-disclosure agreement before being taught?
Writing a love interest for my hero
How to stabilise the bicycle seatpost and saddle when it is all the way up?
Is English tonal for some words, like "permit"?
Honourable versus Right Honourable Members
Do all humans have an identical nucleotide sequence for certain proteins, e.g haemoglobin?
Where does the expression "triple-A" comes from?
Why the word "rain" is considered a verb if it is not possible to conjugate it?
Kerning feedback on logo
Can I cast Sunbeam if both my hands are busy?
Using the pipe operator ("|") when executing system commands
Relevance of the Resurrection
Karma showing this error TypeError: Cannot read property 'textContent' of undefined
Angular2 NgModel not getting value in Jasmine testKarma-Jasmine TypeError: this.ngRedux.getState is not a functionkarma TypeError “Cannot read property 'subscribe' of undefined”Karma: Cannot read property * of undefinedError karma on watch => ERROR in TypeError: Cannot read property 'length' of undefinedJasmine / karma error as cannot read property of undefinedUncaught TypeError: Cannot read property 'length' of undefined - Jasmine/Karma Angualr2TypeError: Cannot read property 'fetchData' of undefined jasmine-karmaTypeerror cannot read property 'triggereventhandler' of undefined in Karma-Jasmine testing
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
I am writing a very basic unit test. I don't know what to do with it. I have tried so many things but cannot be able to resolve this error. Except first test other test is failing.
Spec file
fdescribe("New TestOrder ICD10 Code Selection Modal Component", () =>
let component: NewTestOrderICD10CodeSelectionModalComponent;
let fixture: ComponentFixture<NewTestOrderICD10CodeSelectionModalComponent>;
let de: DebugElement;
let element: HTMLElement;
beforeEach(async (() =>
TestBed.configureTestingModule(
declarations: [
NewTestOrderICD10CodeSelectionModalComponent
],
imports: [
ReactiveFormsModule,
NgbModule.forRoot(),
FormsModule,
RouterTestingModule,
StoreModule.forRoot(),
HttpModule
],
providers: [
AuthService,
UtilService,
SessionService,
TestOrderService,
provide: APP_BASE_HREF, useValue : '/'
],
schemas: [
NO_ERRORS_SCHEMA
]
).compileComponents();
));
beforeEach(async() =>
fixture = TestBed.createComponent(NewTestOrderICD10CodeSelectionModalComponent);
component = fixture.debugElement.componentInstance;
de = fixture.debugElement.query(By.css('.new-test-order-icd10-code-selection-modal.component'));
element = de.nativeElement;
fixture.detectChanges();
);
it("New Test Order ICD10 Coed Selection Modal Should be created", () =>
expect(component).toBeTruthy();
);
it('Should have a title', () =>
expect(element.textContent).toContain(component.title);
);
);
Here is mew-test-order-icd10-code-selection-modal.component.ts file
// Angular DOM
import Component, ViewChild, TemplateRef, OnDestroy from "@angular/core";
// Angular Hooks
import OnInit, AfterViewInit from "@angular/core";
// Redux Store
import Store from "@ngrx/store";
import SetTestOrderCodeSelectionSession from "../../../../shared";
// Models
import
TestOrder,
TestOrderCodeSelectionSession
from "../../../../shared/models";
// Third Party Services
import NgbModal, NgbModalOptions from "@ng-bootstrap/ng-bootstrap";
import ActivatedRoute, Router from "@angular/router";
import * as lodash from "lodash";
// Services
import TestOrderService from "../../../../shared";
import SetTestOrderICDCodes from "../../../../shared/actions/test-order.actions";
import Subscription from "rxjs/Subscription";
@Component(
selector: "app-new-test-order-icd10-code-selection-modal",
templateUrl: "./new-test-order-icd10-code-selection-modal.component.html",
styleUrls: ["./new-test-order-icd10-code-selection-modal.component.scss"]
)
export class NewTestOrderICD10CodeSelectionModalComponent
implements OnInit, AfterViewInit, OnDestroy
@ViewChild("icd10codes") template: TemplateRef<any>;
public codeSelectionSession: TestOrderCodeSelectionSession;
public icdCodes: Array<ICDCode>;
public newIcdCodesArray = [];
public modalRef: any;
title: string = "Please Select ICD-10 Codes";
public serviceSubscription: Subscription;
private selectedCodes: Array<ICDCode> = [];
private options: NgbModalOptions =
backdrop: "static",
windowClass: "icd10-codes",
container: "app-new-test-order-icd10-code-selection-modal",
keyboard: false,
size: "lg"
;
constructor(
private modalService: NgbModal,
private testOrderService: TestOrderService,
public router: Router,
private route: ActivatedRoute,
private store: Store<any>
)
ngOnInit()
this.serviceSubscription = this.testOrderService.getICDCodes().subscribe((codes: Array<ICDCode>) =>
this.icdCodes = codes;
);
this.store
.select("codeSelectionSession")
.subscribe((session: TestOrderCodeSelectionSession) =>
// checks for null and undefined
if (session == null)
this.store.select("testOrder").subscribe((testOrder: TestOrder) =>
this.codeSelectionSession = new TestOrderCodeSelectionSession();
this.store.dispatch(
new SetTestOrderCodeSelectionSession(this.codeSelectionSession)
);
);
else
this.codeSelectionSession = session;
);
ngAfterViewInit()
setTimeout(() =>
this.modalRef = this.modalService.open(this.template, this.options);
);
this.serviceSubscription = this.route.queryParams.subscribe(params =>
//for selected icd
if(params.selectedIcdCodes)
this.selectedCodes = JSON.parse(params.selectedIcdCodes);
this.codeSelectionSession.SelectedCodes = lodash.concat(this.codeSelectionSession.SelectedCodes, this.selectedCodes);
//for icd id
this.codeSelectionSession.ICDCodeIds = lodash.concat(this.codeSelectionSession.ICDCodeIds, params.icd10Codes);
this.newIcdCodesArray = lodash.concat(this.newIcdCodesArray, params.icd10Codes);
this.codeSelectionSession.ICDCodeIds = lodash.uniq(this.codeSelectionSession.ICDCodeIds);
let difference = lodash.difference(this.codeSelectionSession.ICDCodeIds, this.newIcdCodesArray);
this.codeSelectionSession.ICDCodeIds = lodash.differenceBy(this.codeSelectionSession.ICDCodeIds, difference); //remove the difference
);
onCheckboxUpdate(selected: boolean, icdCode: ICDCode)
this.codeSelectionSession.ICDCodeIds = this.codeSelectionSession.ICDCodeIds.filter(
codeId => codeId !== icdCode.Id
);
this.codeSelectionSession.SelectedCodes = this.codeSelectionSession.SelectedCodes.filter(
code => code.Id !== icdCode.Id
);
if (selected)
this.codeSelectionSession.ICDCodeIds.push(icdCode.Id);
this.codeSelectionSession.SelectedCodes.push(icdCode);
ngOnDestroy()
setTimeout(() =>
this.modalRef.close();
);
this.serviceSubscription.unsubscribe();
The second test should pass as well. I don't know what i am doing wrong here.
Another method i tried.
This is my specfile by doing this its showing me Cannot read property 'nativeElement' of null
beforeEach(async() =>
fixture = TestBed.createComponent(NewTestOrderICD10CodeSelectionModalComponent);
component = fixture.debugElement.componentInstance;
// de = fixture.debugElement.query(By.css('.h5')).nativeElement.innerText;
// element = de.nativeElement;
fixture.detectChanges();
);
it("New Test Order ICD10 Coed Selection Modal Should be created", () =>
expect(component).toBeTruthy();
);
it('Should have a title', () =>
//expect(element.textContent).toContain(component.title);
fixture.detectChanges();
const de = fixture.debugElement.query(By.css('.modal-title')).nativeElement.innerText;
expect(de).toContain(component.title);
);
This is my html file
<ng-template #icd10codes let-c="close" let-d="dismiss">
<form role="form" #icdCodeSelectionForm="ngForm" novalidate>
<div class="modal-header">
<span class="material-icons clickable text-dimmed" (click)="onBackButtonClick()" [routerLink]="['/test-order/create/details']">arrow_back</span>
<h5 class="modal-title">title</h5>
<button type="button" class="btn square-btn" (click)="update()">ADD CODES</button>
<div class="icd-search">
<app-search-list (onSearchInputUpdate)="onSearchUpdate($event)"></app-search-list>
</div>
</div>
<div class="modal-body">
<div class="row">
<div class="col-3 text-dimmed pad-left-45">ICD-10 Codes</div>
<div class="col-8 text-dimmed">Description</div>
<div class="col-1"></div>
</div>
<div class="list-border"></div>
<div class="code-list">
<div class="row" *ngFor="let icdCode of icdCodes; let odd = odd" [ngClass]="'isOdd': odd">
<div class="col-3 pad-left-45"> icdCode.Code </div>
<div class="col-8 text-dimmed"> icdCode.ShortDescription </div>
<div class="col-1">
<label class="custom-control custom-checkbox">
<input
type="checkbox"
class="custom-control-input"
[ngModel]="codeSelectionSession.ICDCodeIds.indexOf(icdCode.Id) !== -1"
(ngModelChange)="onCheckboxUpdate($event, icdCode)"
[name]="icdCode.Id">
<span class="custom-control-indicator"></span>
</label>
</div>
</div>
</div>
</div>
</form>
</ng-template>
angular unit-testing jasmine karma-jasmine karma-webpack
|
show 5 more comments
I am writing a very basic unit test. I don't know what to do with it. I have tried so many things but cannot be able to resolve this error. Except first test other test is failing.
Spec file
fdescribe("New TestOrder ICD10 Code Selection Modal Component", () =>
let component: NewTestOrderICD10CodeSelectionModalComponent;
let fixture: ComponentFixture<NewTestOrderICD10CodeSelectionModalComponent>;
let de: DebugElement;
let element: HTMLElement;
beforeEach(async (() =>
TestBed.configureTestingModule(
declarations: [
NewTestOrderICD10CodeSelectionModalComponent
],
imports: [
ReactiveFormsModule,
NgbModule.forRoot(),
FormsModule,
RouterTestingModule,
StoreModule.forRoot(),
HttpModule
],
providers: [
AuthService,
UtilService,
SessionService,
TestOrderService,
provide: APP_BASE_HREF, useValue : '/'
],
schemas: [
NO_ERRORS_SCHEMA
]
).compileComponents();
));
beforeEach(async() =>
fixture = TestBed.createComponent(NewTestOrderICD10CodeSelectionModalComponent);
component = fixture.debugElement.componentInstance;
de = fixture.debugElement.query(By.css('.new-test-order-icd10-code-selection-modal.component'));
element = de.nativeElement;
fixture.detectChanges();
);
it("New Test Order ICD10 Coed Selection Modal Should be created", () =>
expect(component).toBeTruthy();
);
it('Should have a title', () =>
expect(element.textContent).toContain(component.title);
);
);
Here is mew-test-order-icd10-code-selection-modal.component.ts file
// Angular DOM
import Component, ViewChild, TemplateRef, OnDestroy from "@angular/core";
// Angular Hooks
import OnInit, AfterViewInit from "@angular/core";
// Redux Store
import Store from "@ngrx/store";
import SetTestOrderCodeSelectionSession from "../../../../shared";
// Models
import
TestOrder,
TestOrderCodeSelectionSession
from "../../../../shared/models";
// Third Party Services
import NgbModal, NgbModalOptions from "@ng-bootstrap/ng-bootstrap";
import ActivatedRoute, Router from "@angular/router";
import * as lodash from "lodash";
// Services
import TestOrderService from "../../../../shared";
import SetTestOrderICDCodes from "../../../../shared/actions/test-order.actions";
import Subscription from "rxjs/Subscription";
@Component(
selector: "app-new-test-order-icd10-code-selection-modal",
templateUrl: "./new-test-order-icd10-code-selection-modal.component.html",
styleUrls: ["./new-test-order-icd10-code-selection-modal.component.scss"]
)
export class NewTestOrderICD10CodeSelectionModalComponent
implements OnInit, AfterViewInit, OnDestroy
@ViewChild("icd10codes") template: TemplateRef<any>;
public codeSelectionSession: TestOrderCodeSelectionSession;
public icdCodes: Array<ICDCode>;
public newIcdCodesArray = [];
public modalRef: any;
title: string = "Please Select ICD-10 Codes";
public serviceSubscription: Subscription;
private selectedCodes: Array<ICDCode> = [];
private options: NgbModalOptions =
backdrop: "static",
windowClass: "icd10-codes",
container: "app-new-test-order-icd10-code-selection-modal",
keyboard: false,
size: "lg"
;
constructor(
private modalService: NgbModal,
private testOrderService: TestOrderService,
public router: Router,
private route: ActivatedRoute,
private store: Store<any>
)
ngOnInit()
this.serviceSubscription = this.testOrderService.getICDCodes().subscribe((codes: Array<ICDCode>) =>
this.icdCodes = codes;
);
this.store
.select("codeSelectionSession")
.subscribe((session: TestOrderCodeSelectionSession) =>
// checks for null and undefined
if (session == null)
this.store.select("testOrder").subscribe((testOrder: TestOrder) =>
this.codeSelectionSession = new TestOrderCodeSelectionSession();
this.store.dispatch(
new SetTestOrderCodeSelectionSession(this.codeSelectionSession)
);
);
else
this.codeSelectionSession = session;
);
ngAfterViewInit()
setTimeout(() =>
this.modalRef = this.modalService.open(this.template, this.options);
);
this.serviceSubscription = this.route.queryParams.subscribe(params =>
//for selected icd
if(params.selectedIcdCodes)
this.selectedCodes = JSON.parse(params.selectedIcdCodes);
this.codeSelectionSession.SelectedCodes = lodash.concat(this.codeSelectionSession.SelectedCodes, this.selectedCodes);
//for icd id
this.codeSelectionSession.ICDCodeIds = lodash.concat(this.codeSelectionSession.ICDCodeIds, params.icd10Codes);
this.newIcdCodesArray = lodash.concat(this.newIcdCodesArray, params.icd10Codes);
this.codeSelectionSession.ICDCodeIds = lodash.uniq(this.codeSelectionSession.ICDCodeIds);
let difference = lodash.difference(this.codeSelectionSession.ICDCodeIds, this.newIcdCodesArray);
this.codeSelectionSession.ICDCodeIds = lodash.differenceBy(this.codeSelectionSession.ICDCodeIds, difference); //remove the difference
);
onCheckboxUpdate(selected: boolean, icdCode: ICDCode)
this.codeSelectionSession.ICDCodeIds = this.codeSelectionSession.ICDCodeIds.filter(
codeId => codeId !== icdCode.Id
);
this.codeSelectionSession.SelectedCodes = this.codeSelectionSession.SelectedCodes.filter(
code => code.Id !== icdCode.Id
);
if (selected)
this.codeSelectionSession.ICDCodeIds.push(icdCode.Id);
this.codeSelectionSession.SelectedCodes.push(icdCode);
ngOnDestroy()
setTimeout(() =>
this.modalRef.close();
);
this.serviceSubscription.unsubscribe();
The second test should pass as well. I don't know what i am doing wrong here.
Another method i tried.
This is my specfile by doing this its showing me Cannot read property 'nativeElement' of null
beforeEach(async() =>
fixture = TestBed.createComponent(NewTestOrderICD10CodeSelectionModalComponent);
component = fixture.debugElement.componentInstance;
// de = fixture.debugElement.query(By.css('.h5')).nativeElement.innerText;
// element = de.nativeElement;
fixture.detectChanges();
);
it("New Test Order ICD10 Coed Selection Modal Should be created", () =>
expect(component).toBeTruthy();
);
it('Should have a title', () =>
//expect(element.textContent).toContain(component.title);
fixture.detectChanges();
const de = fixture.debugElement.query(By.css('.modal-title')).nativeElement.innerText;
expect(de).toContain(component.title);
);
This is my html file
<ng-template #icd10codes let-c="close" let-d="dismiss">
<form role="form" #icdCodeSelectionForm="ngForm" novalidate>
<div class="modal-header">
<span class="material-icons clickable text-dimmed" (click)="onBackButtonClick()" [routerLink]="['/test-order/create/details']">arrow_back</span>
<h5 class="modal-title">title</h5>
<button type="button" class="btn square-btn" (click)="update()">ADD CODES</button>
<div class="icd-search">
<app-search-list (onSearchInputUpdate)="onSearchUpdate($event)"></app-search-list>
</div>
</div>
<div class="modal-body">
<div class="row">
<div class="col-3 text-dimmed pad-left-45">ICD-10 Codes</div>
<div class="col-8 text-dimmed">Description</div>
<div class="col-1"></div>
</div>
<div class="list-border"></div>
<div class="code-list">
<div class="row" *ngFor="let icdCode of icdCodes; let odd = odd" [ngClass]="'isOdd': odd">
<div class="col-3 pad-left-45"> icdCode.Code </div>
<div class="col-8 text-dimmed"> icdCode.ShortDescription </div>
<div class="col-1">
<label class="custom-control custom-checkbox">
<input
type="checkbox"
class="custom-control-input"
[ngModel]="codeSelectionSession.ICDCodeIds.indexOf(icdCode.Id) !== -1"
(ngModelChange)="onCheckboxUpdate($event, icdCode)"
[name]="icdCode.Id">
<span class="custom-control-indicator"></span>
</label>
</div>
</div>
</div>
</div>
</form>
</ng-template>
angular unit-testing jasmine karma-jasmine karma-webpack
It is not finding element.textContent because your thread(async) running before having any values in element.textContent
– atishr
Mar 28 at 7:26
@ShashankVivek i tried but its still not working may be its because of my html file i closed it in ng-template ?
– Salman Ahmad
Mar 29 at 5:40
@SalmanAhmad : what is the condition to render#icd10codes
on html ?? Please update entire html code in the post andnot
in the comments :) .ng-template
is not rendered by default. So, your test case wont find it
– Shashank Vivek
Mar 29 at 5:58
@ShashankVivek Thanks for taking the time i have updated it with my html code :)
– Salman Ahmad
Mar 29 at 6:07
1
@ShashankVivek Yes this is the full html file. Actually what is happening here is this components ng-template only gets true when you click on this components field on its parent component. So when i am testing its not actually loading the component thats the reason now after trying your described method of writing test its showing this error Expected undefined to contain Please Select ICD-10 Codes i guess i would have to implement it differently .. I appreciate you taking the time and look into this you helped me alot Thanks :)
– Salman Ahmad
Mar 29 at 12:06
|
show 5 more comments
I am writing a very basic unit test. I don't know what to do with it. I have tried so many things but cannot be able to resolve this error. Except first test other test is failing.
Spec file
fdescribe("New TestOrder ICD10 Code Selection Modal Component", () =>
let component: NewTestOrderICD10CodeSelectionModalComponent;
let fixture: ComponentFixture<NewTestOrderICD10CodeSelectionModalComponent>;
let de: DebugElement;
let element: HTMLElement;
beforeEach(async (() =>
TestBed.configureTestingModule(
declarations: [
NewTestOrderICD10CodeSelectionModalComponent
],
imports: [
ReactiveFormsModule,
NgbModule.forRoot(),
FormsModule,
RouterTestingModule,
StoreModule.forRoot(),
HttpModule
],
providers: [
AuthService,
UtilService,
SessionService,
TestOrderService,
provide: APP_BASE_HREF, useValue : '/'
],
schemas: [
NO_ERRORS_SCHEMA
]
).compileComponents();
));
beforeEach(async() =>
fixture = TestBed.createComponent(NewTestOrderICD10CodeSelectionModalComponent);
component = fixture.debugElement.componentInstance;
de = fixture.debugElement.query(By.css('.new-test-order-icd10-code-selection-modal.component'));
element = de.nativeElement;
fixture.detectChanges();
);
it("New Test Order ICD10 Coed Selection Modal Should be created", () =>
expect(component).toBeTruthy();
);
it('Should have a title', () =>
expect(element.textContent).toContain(component.title);
);
);
Here is mew-test-order-icd10-code-selection-modal.component.ts file
// Angular DOM
import Component, ViewChild, TemplateRef, OnDestroy from "@angular/core";
// Angular Hooks
import OnInit, AfterViewInit from "@angular/core";
// Redux Store
import Store from "@ngrx/store";
import SetTestOrderCodeSelectionSession from "../../../../shared";
// Models
import
TestOrder,
TestOrderCodeSelectionSession
from "../../../../shared/models";
// Third Party Services
import NgbModal, NgbModalOptions from "@ng-bootstrap/ng-bootstrap";
import ActivatedRoute, Router from "@angular/router";
import * as lodash from "lodash";
// Services
import TestOrderService from "../../../../shared";
import SetTestOrderICDCodes from "../../../../shared/actions/test-order.actions";
import Subscription from "rxjs/Subscription";
@Component(
selector: "app-new-test-order-icd10-code-selection-modal",
templateUrl: "./new-test-order-icd10-code-selection-modal.component.html",
styleUrls: ["./new-test-order-icd10-code-selection-modal.component.scss"]
)
export class NewTestOrderICD10CodeSelectionModalComponent
implements OnInit, AfterViewInit, OnDestroy
@ViewChild("icd10codes") template: TemplateRef<any>;
public codeSelectionSession: TestOrderCodeSelectionSession;
public icdCodes: Array<ICDCode>;
public newIcdCodesArray = [];
public modalRef: any;
title: string = "Please Select ICD-10 Codes";
public serviceSubscription: Subscription;
private selectedCodes: Array<ICDCode> = [];
private options: NgbModalOptions =
backdrop: "static",
windowClass: "icd10-codes",
container: "app-new-test-order-icd10-code-selection-modal",
keyboard: false,
size: "lg"
;
constructor(
private modalService: NgbModal,
private testOrderService: TestOrderService,
public router: Router,
private route: ActivatedRoute,
private store: Store<any>
)
ngOnInit()
this.serviceSubscription = this.testOrderService.getICDCodes().subscribe((codes: Array<ICDCode>) =>
this.icdCodes = codes;
);
this.store
.select("codeSelectionSession")
.subscribe((session: TestOrderCodeSelectionSession) =>
// checks for null and undefined
if (session == null)
this.store.select("testOrder").subscribe((testOrder: TestOrder) =>
this.codeSelectionSession = new TestOrderCodeSelectionSession();
this.store.dispatch(
new SetTestOrderCodeSelectionSession(this.codeSelectionSession)
);
);
else
this.codeSelectionSession = session;
);
ngAfterViewInit()
setTimeout(() =>
this.modalRef = this.modalService.open(this.template, this.options);
);
this.serviceSubscription = this.route.queryParams.subscribe(params =>
//for selected icd
if(params.selectedIcdCodes)
this.selectedCodes = JSON.parse(params.selectedIcdCodes);
this.codeSelectionSession.SelectedCodes = lodash.concat(this.codeSelectionSession.SelectedCodes, this.selectedCodes);
//for icd id
this.codeSelectionSession.ICDCodeIds = lodash.concat(this.codeSelectionSession.ICDCodeIds, params.icd10Codes);
this.newIcdCodesArray = lodash.concat(this.newIcdCodesArray, params.icd10Codes);
this.codeSelectionSession.ICDCodeIds = lodash.uniq(this.codeSelectionSession.ICDCodeIds);
let difference = lodash.difference(this.codeSelectionSession.ICDCodeIds, this.newIcdCodesArray);
this.codeSelectionSession.ICDCodeIds = lodash.differenceBy(this.codeSelectionSession.ICDCodeIds, difference); //remove the difference
);
onCheckboxUpdate(selected: boolean, icdCode: ICDCode)
this.codeSelectionSession.ICDCodeIds = this.codeSelectionSession.ICDCodeIds.filter(
codeId => codeId !== icdCode.Id
);
this.codeSelectionSession.SelectedCodes = this.codeSelectionSession.SelectedCodes.filter(
code => code.Id !== icdCode.Id
);
if (selected)
this.codeSelectionSession.ICDCodeIds.push(icdCode.Id);
this.codeSelectionSession.SelectedCodes.push(icdCode);
ngOnDestroy()
setTimeout(() =>
this.modalRef.close();
);
this.serviceSubscription.unsubscribe();
The second test should pass as well. I don't know what i am doing wrong here.
Another method i tried.
This is my specfile by doing this its showing me Cannot read property 'nativeElement' of null
beforeEach(async() =>
fixture = TestBed.createComponent(NewTestOrderICD10CodeSelectionModalComponent);
component = fixture.debugElement.componentInstance;
// de = fixture.debugElement.query(By.css('.h5')).nativeElement.innerText;
// element = de.nativeElement;
fixture.detectChanges();
);
it("New Test Order ICD10 Coed Selection Modal Should be created", () =>
expect(component).toBeTruthy();
);
it('Should have a title', () =>
//expect(element.textContent).toContain(component.title);
fixture.detectChanges();
const de = fixture.debugElement.query(By.css('.modal-title')).nativeElement.innerText;
expect(de).toContain(component.title);
);
This is my html file
<ng-template #icd10codes let-c="close" let-d="dismiss">
<form role="form" #icdCodeSelectionForm="ngForm" novalidate>
<div class="modal-header">
<span class="material-icons clickable text-dimmed" (click)="onBackButtonClick()" [routerLink]="['/test-order/create/details']">arrow_back</span>
<h5 class="modal-title">title</h5>
<button type="button" class="btn square-btn" (click)="update()">ADD CODES</button>
<div class="icd-search">
<app-search-list (onSearchInputUpdate)="onSearchUpdate($event)"></app-search-list>
</div>
</div>
<div class="modal-body">
<div class="row">
<div class="col-3 text-dimmed pad-left-45">ICD-10 Codes</div>
<div class="col-8 text-dimmed">Description</div>
<div class="col-1"></div>
</div>
<div class="list-border"></div>
<div class="code-list">
<div class="row" *ngFor="let icdCode of icdCodes; let odd = odd" [ngClass]="'isOdd': odd">
<div class="col-3 pad-left-45"> icdCode.Code </div>
<div class="col-8 text-dimmed"> icdCode.ShortDescription </div>
<div class="col-1">
<label class="custom-control custom-checkbox">
<input
type="checkbox"
class="custom-control-input"
[ngModel]="codeSelectionSession.ICDCodeIds.indexOf(icdCode.Id) !== -1"
(ngModelChange)="onCheckboxUpdate($event, icdCode)"
[name]="icdCode.Id">
<span class="custom-control-indicator"></span>
</label>
</div>
</div>
</div>
</div>
</form>
</ng-template>
angular unit-testing jasmine karma-jasmine karma-webpack
I am writing a very basic unit test. I don't know what to do with it. I have tried so many things but cannot be able to resolve this error. Except first test other test is failing.
Spec file
fdescribe("New TestOrder ICD10 Code Selection Modal Component", () =>
let component: NewTestOrderICD10CodeSelectionModalComponent;
let fixture: ComponentFixture<NewTestOrderICD10CodeSelectionModalComponent>;
let de: DebugElement;
let element: HTMLElement;
beforeEach(async (() =>
TestBed.configureTestingModule(
declarations: [
NewTestOrderICD10CodeSelectionModalComponent
],
imports: [
ReactiveFormsModule,
NgbModule.forRoot(),
FormsModule,
RouterTestingModule,
StoreModule.forRoot(),
HttpModule
],
providers: [
AuthService,
UtilService,
SessionService,
TestOrderService,
provide: APP_BASE_HREF, useValue : '/'
],
schemas: [
NO_ERRORS_SCHEMA
]
).compileComponents();
));
beforeEach(async() =>
fixture = TestBed.createComponent(NewTestOrderICD10CodeSelectionModalComponent);
component = fixture.debugElement.componentInstance;
de = fixture.debugElement.query(By.css('.new-test-order-icd10-code-selection-modal.component'));
element = de.nativeElement;
fixture.detectChanges();
);
it("New Test Order ICD10 Coed Selection Modal Should be created", () =>
expect(component).toBeTruthy();
);
it('Should have a title', () =>
expect(element.textContent).toContain(component.title);
);
);
Here is mew-test-order-icd10-code-selection-modal.component.ts file
// Angular DOM
import Component, ViewChild, TemplateRef, OnDestroy from "@angular/core";
// Angular Hooks
import OnInit, AfterViewInit from "@angular/core";
// Redux Store
import Store from "@ngrx/store";
import SetTestOrderCodeSelectionSession from "../../../../shared";
// Models
import
TestOrder,
TestOrderCodeSelectionSession
from "../../../../shared/models";
// Third Party Services
import NgbModal, NgbModalOptions from "@ng-bootstrap/ng-bootstrap";
import ActivatedRoute, Router from "@angular/router";
import * as lodash from "lodash";
// Services
import TestOrderService from "../../../../shared";
import SetTestOrderICDCodes from "../../../../shared/actions/test-order.actions";
import Subscription from "rxjs/Subscription";
@Component(
selector: "app-new-test-order-icd10-code-selection-modal",
templateUrl: "./new-test-order-icd10-code-selection-modal.component.html",
styleUrls: ["./new-test-order-icd10-code-selection-modal.component.scss"]
)
export class NewTestOrderICD10CodeSelectionModalComponent
implements OnInit, AfterViewInit, OnDestroy
@ViewChild("icd10codes") template: TemplateRef<any>;
public codeSelectionSession: TestOrderCodeSelectionSession;
public icdCodes: Array<ICDCode>;
public newIcdCodesArray = [];
public modalRef: any;
title: string = "Please Select ICD-10 Codes";
public serviceSubscription: Subscription;
private selectedCodes: Array<ICDCode> = [];
private options: NgbModalOptions =
backdrop: "static",
windowClass: "icd10-codes",
container: "app-new-test-order-icd10-code-selection-modal",
keyboard: false,
size: "lg"
;
constructor(
private modalService: NgbModal,
private testOrderService: TestOrderService,
public router: Router,
private route: ActivatedRoute,
private store: Store<any>
)
ngOnInit()
this.serviceSubscription = this.testOrderService.getICDCodes().subscribe((codes: Array<ICDCode>) =>
this.icdCodes = codes;
);
this.store
.select("codeSelectionSession")
.subscribe((session: TestOrderCodeSelectionSession) =>
// checks for null and undefined
if (session == null)
this.store.select("testOrder").subscribe((testOrder: TestOrder) =>
this.codeSelectionSession = new TestOrderCodeSelectionSession();
this.store.dispatch(
new SetTestOrderCodeSelectionSession(this.codeSelectionSession)
);
);
else
this.codeSelectionSession = session;
);
ngAfterViewInit()
setTimeout(() =>
this.modalRef = this.modalService.open(this.template, this.options);
);
this.serviceSubscription = this.route.queryParams.subscribe(params =>
//for selected icd
if(params.selectedIcdCodes)
this.selectedCodes = JSON.parse(params.selectedIcdCodes);
this.codeSelectionSession.SelectedCodes = lodash.concat(this.codeSelectionSession.SelectedCodes, this.selectedCodes);
//for icd id
this.codeSelectionSession.ICDCodeIds = lodash.concat(this.codeSelectionSession.ICDCodeIds, params.icd10Codes);
this.newIcdCodesArray = lodash.concat(this.newIcdCodesArray, params.icd10Codes);
this.codeSelectionSession.ICDCodeIds = lodash.uniq(this.codeSelectionSession.ICDCodeIds);
let difference = lodash.difference(this.codeSelectionSession.ICDCodeIds, this.newIcdCodesArray);
this.codeSelectionSession.ICDCodeIds = lodash.differenceBy(this.codeSelectionSession.ICDCodeIds, difference); //remove the difference
);
onCheckboxUpdate(selected: boolean, icdCode: ICDCode)
this.codeSelectionSession.ICDCodeIds = this.codeSelectionSession.ICDCodeIds.filter(
codeId => codeId !== icdCode.Id
);
this.codeSelectionSession.SelectedCodes = this.codeSelectionSession.SelectedCodes.filter(
code => code.Id !== icdCode.Id
);
if (selected)
this.codeSelectionSession.ICDCodeIds.push(icdCode.Id);
this.codeSelectionSession.SelectedCodes.push(icdCode);
ngOnDestroy()
setTimeout(() =>
this.modalRef.close();
);
this.serviceSubscription.unsubscribe();
The second test should pass as well. I don't know what i am doing wrong here.
Another method i tried.
This is my specfile by doing this its showing me Cannot read property 'nativeElement' of null
beforeEach(async() =>
fixture = TestBed.createComponent(NewTestOrderICD10CodeSelectionModalComponent);
component = fixture.debugElement.componentInstance;
// de = fixture.debugElement.query(By.css('.h5')).nativeElement.innerText;
// element = de.nativeElement;
fixture.detectChanges();
);
it("New Test Order ICD10 Coed Selection Modal Should be created", () =>
expect(component).toBeTruthy();
);
it('Should have a title', () =>
//expect(element.textContent).toContain(component.title);
fixture.detectChanges();
const de = fixture.debugElement.query(By.css('.modal-title')).nativeElement.innerText;
expect(de).toContain(component.title);
);
This is my html file
<ng-template #icd10codes let-c="close" let-d="dismiss">
<form role="form" #icdCodeSelectionForm="ngForm" novalidate>
<div class="modal-header">
<span class="material-icons clickable text-dimmed" (click)="onBackButtonClick()" [routerLink]="['/test-order/create/details']">arrow_back</span>
<h5 class="modal-title">title</h5>
<button type="button" class="btn square-btn" (click)="update()">ADD CODES</button>
<div class="icd-search">
<app-search-list (onSearchInputUpdate)="onSearchUpdate($event)"></app-search-list>
</div>
</div>
<div class="modal-body">
<div class="row">
<div class="col-3 text-dimmed pad-left-45">ICD-10 Codes</div>
<div class="col-8 text-dimmed">Description</div>
<div class="col-1"></div>
</div>
<div class="list-border"></div>
<div class="code-list">
<div class="row" *ngFor="let icdCode of icdCodes; let odd = odd" [ngClass]="'isOdd': odd">
<div class="col-3 pad-left-45"> icdCode.Code </div>
<div class="col-8 text-dimmed"> icdCode.ShortDescription </div>
<div class="col-1">
<label class="custom-control custom-checkbox">
<input
type="checkbox"
class="custom-control-input"
[ngModel]="codeSelectionSession.ICDCodeIds.indexOf(icdCode.Id) !== -1"
(ngModelChange)="onCheckboxUpdate($event, icdCode)"
[name]="icdCode.Id">
<span class="custom-control-indicator"></span>
</label>
</div>
</div>
</div>
</div>
</form>
</ng-template>
angular unit-testing jasmine karma-jasmine karma-webpack
angular unit-testing jasmine karma-jasmine karma-webpack
edited Mar 29 at 10:24
Salman Ahmad
asked Mar 28 at 7:18
Salman AhmadSalman Ahmad
65 bronze badges
65 bronze badges
It is not finding element.textContent because your thread(async) running before having any values in element.textContent
– atishr
Mar 28 at 7:26
@ShashankVivek i tried but its still not working may be its because of my html file i closed it in ng-template ?
– Salman Ahmad
Mar 29 at 5:40
@SalmanAhmad : what is the condition to render#icd10codes
on html ?? Please update entire html code in the post andnot
in the comments :) .ng-template
is not rendered by default. So, your test case wont find it
– Shashank Vivek
Mar 29 at 5:58
@ShashankVivek Thanks for taking the time i have updated it with my html code :)
– Salman Ahmad
Mar 29 at 6:07
1
@ShashankVivek Yes this is the full html file. Actually what is happening here is this components ng-template only gets true when you click on this components field on its parent component. So when i am testing its not actually loading the component thats the reason now after trying your described method of writing test its showing this error Expected undefined to contain Please Select ICD-10 Codes i guess i would have to implement it differently .. I appreciate you taking the time and look into this you helped me alot Thanks :)
– Salman Ahmad
Mar 29 at 12:06
|
show 5 more comments
It is not finding element.textContent because your thread(async) running before having any values in element.textContent
– atishr
Mar 28 at 7:26
@ShashankVivek i tried but its still not working may be its because of my html file i closed it in ng-template ?
– Salman Ahmad
Mar 29 at 5:40
@SalmanAhmad : what is the condition to render#icd10codes
on html ?? Please update entire html code in the post andnot
in the comments :) .ng-template
is not rendered by default. So, your test case wont find it
– Shashank Vivek
Mar 29 at 5:58
@ShashankVivek Thanks for taking the time i have updated it with my html code :)
– Salman Ahmad
Mar 29 at 6:07
1
@ShashankVivek Yes this is the full html file. Actually what is happening here is this components ng-template only gets true when you click on this components field on its parent component. So when i am testing its not actually loading the component thats the reason now after trying your described method of writing test its showing this error Expected undefined to contain Please Select ICD-10 Codes i guess i would have to implement it differently .. I appreciate you taking the time and look into this you helped me alot Thanks :)
– Salman Ahmad
Mar 29 at 12:06
It is not finding element.textContent because your thread(async) running before having any values in element.textContent
– atishr
Mar 28 at 7:26
It is not finding element.textContent because your thread(async) running before having any values in element.textContent
– atishr
Mar 28 at 7:26
@ShashankVivek i tried but its still not working may be its because of my html file i closed it in ng-template ?
– Salman Ahmad
Mar 29 at 5:40
@ShashankVivek i tried but its still not working may be its because of my html file i closed it in ng-template ?
– Salman Ahmad
Mar 29 at 5:40
@SalmanAhmad : what is the condition to render
#icd10codes
on html ?? Please update entire html code in the post and not
in the comments :) . ng-template
is not rendered by default. So, your test case wont find it– Shashank Vivek
Mar 29 at 5:58
@SalmanAhmad : what is the condition to render
#icd10codes
on html ?? Please update entire html code in the post and not
in the comments :) . ng-template
is not rendered by default. So, your test case wont find it– Shashank Vivek
Mar 29 at 5:58
@ShashankVivek Thanks for taking the time i have updated it with my html code :)
– Salman Ahmad
Mar 29 at 6:07
@ShashankVivek Thanks for taking the time i have updated it with my html code :)
– Salman Ahmad
Mar 29 at 6:07
1
1
@ShashankVivek Yes this is the full html file. Actually what is happening here is this components ng-template only gets true when you click on this components field on its parent component. So when i am testing its not actually loading the component thats the reason now after trying your described method of writing test its showing this error Expected undefined to contain Please Select ICD-10 Codes i guess i would have to implement it differently .. I appreciate you taking the time and look into this you helped me alot Thanks :)
– Salman Ahmad
Mar 29 at 12:06
@ShashankVivek Yes this is the full html file. Actually what is happening here is this components ng-template only gets true when you click on this components field on its parent component. So when i am testing its not actually loading the component thats the reason now after trying your described method of writing test its showing this error Expected undefined to contain Please Select ICD-10 Codes i guess i would have to implement it differently .. I appreciate you taking the time and look into this you helped me alot Thanks :)
– Salman Ahmad
Mar 29 at 12:06
|
show 5 more comments
2 Answers
2
active
oldest
votes
As you are doing element = de.nativeElement;
in beforeEach()
, so the element
contains the value.
And, it can be done through
it('Should have a title', () =>
expect(element).toContain(component.title);
);
From de = fixture.debugElement.query(By......
, de
will be a HTMLNode
, and using nativeElement
on this will get you the content. Or, you can directly use de.textContent
to get the content of the element de
.
Alligator.io Link for Unit testing
add a comment |
My suggestion is to remove
de = fixture.debugElement.query(By.css('.new-test-order-icd10-code-selection-modal.component'));
from beforeEach
block. Please note that, you are trying to get this value before fixture.detectChanges();
, so I think it's not a good approach. You must make sure that you get the HTML values after all the angular changes are complete. Try:
it('Should have a title', () =>
fixture.detectChanges(); // No need to add this line if you have it in "beforeEach" block
const de = fixture.debugElement.query(By.css('.new-test-order-icd10-code-selection-modal.component'));
const element = de.nativeElement;
expect(element.textContent).toContain(component.title);
);
Update
For testing ng-template
you'll have to do it differently:
app.component.html
<div id="title">
title
</div>
<ng-template #content
let-modal
id="ng-modal">
<div class="modal-header dark-modal">
Header
</div>
<div class="justify-content-center flex-column flex-md-row list-inline">
Body
</div>
</ng-template>
app.component.ts
import Component, ViewChild, TemplateRef from '@angular/core';
@Component(
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
)
export class AppComponent
title = 'AngularProj';
@ViewChild('content') modalRef: TemplateRef<any>;
You need to write spec
file with slightly different way:
app.component.spec.ts
import TestBed, async, ComponentFixture from '@angular/core/testing';
import AppComponent from './app.component';
import ViewChild, Component, OnInit, AfterContentInit, TemplateRef from '@angular/core';
import By from '@angular/platform-browser';
@Component(
template: `
<ng-container *ngTemplateOutlet="modal"> </ng-container>
<app-root></app-root>
`,
)
class WrapperComponent implements AfterContentInit
@ViewChild(AppComponent) appComponentRef: AppComponent;
modal: TemplateRef<any>;
ngAfterContentInit()
this.modal = this.appComponentRef.modalRef;
describe('AppComponent', () =>
let app: AppComponent;
let fixture: ComponentFixture<WrapperComponent>;
beforeEach(async(() =>
TestBed.configureTestingModule(
declarations: [WrapperComponent, AppComponent],
).compileComponents();
));
beforeEach(() =>
fixture = TestBed.createComponent(WrapperComponent);
const wrapperComponent = fixture.debugElement.componentInstance;
app = wrapperComponent.appComponentRef;
fixture.detectChanges();
);
it('should create the app', async(() =>
expect(app).toBeDefined();
));
it('should have title in HtmL ', async(() =>
const titleText = (fixture.debugElement.nativeElement.querySelector('#title').innerText);
expect(titleText).toBe('AngularProj');
));
it('should have Header in HtmL ', async(() =>
const headerText = (fixture.debugElement.queryAll(By.css('.modal-header.dark-modal'))[0].nativeElement.innerText);
expect(headerText).toBe('Header');
));
);
- As you can see, I wrapped the
app-root
with a sample testing component (WrapperComponent
). - Since,
app-root
hasng-template
, so it won't render on it's own. This creates a tricky situation as we need to render this part of theapp.component
. - Expose
ng-template
by creating@ViewChild('content') modalRef: TemplateRef<any>;
and then using it to render insideWrapperComponent
.
I know it seems like a hack but over all the articles I went through, that's how we can achieve this.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/4.0/"u003ecc by-sa 4.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55392057%2fkarma-showing-this-error-typeerror-cannot-read-property-textcontent-of-undefi%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
As you are doing element = de.nativeElement;
in beforeEach()
, so the element
contains the value.
And, it can be done through
it('Should have a title', () =>
expect(element).toContain(component.title);
);
From de = fixture.debugElement.query(By......
, de
will be a HTMLNode
, and using nativeElement
on this will get you the content. Or, you can directly use de.textContent
to get the content of the element de
.
Alligator.io Link for Unit testing
add a comment |
As you are doing element = de.nativeElement;
in beforeEach()
, so the element
contains the value.
And, it can be done through
it('Should have a title', () =>
expect(element).toContain(component.title);
);
From de = fixture.debugElement.query(By......
, de
will be a HTMLNode
, and using nativeElement
on this will get you the content. Or, you can directly use de.textContent
to get the content of the element de
.
Alligator.io Link for Unit testing
add a comment |
As you are doing element = de.nativeElement;
in beforeEach()
, so the element
contains the value.
And, it can be done through
it('Should have a title', () =>
expect(element).toContain(component.title);
);
From de = fixture.debugElement.query(By......
, de
will be a HTMLNode
, and using nativeElement
on this will get you the content. Or, you can directly use de.textContent
to get the content of the element de
.
Alligator.io Link for Unit testing
As you are doing element = de.nativeElement;
in beforeEach()
, so the element
contains the value.
And, it can be done through
it('Should have a title', () =>
expect(element).toContain(component.title);
);
From de = fixture.debugElement.query(By......
, de
will be a HTMLNode
, and using nativeElement
on this will get you the content. Or, you can directly use de.textContent
to get the content of the element de
.
Alligator.io Link for Unit testing
edited Mar 28 at 9:39
answered Mar 28 at 9:02
Abhishek KumarAbhishek Kumar
1,6334 silver badges18 bronze badges
1,6334 silver badges18 bronze badges
add a comment |
add a comment |
My suggestion is to remove
de = fixture.debugElement.query(By.css('.new-test-order-icd10-code-selection-modal.component'));
from beforeEach
block. Please note that, you are trying to get this value before fixture.detectChanges();
, so I think it's not a good approach. You must make sure that you get the HTML values after all the angular changes are complete. Try:
it('Should have a title', () =>
fixture.detectChanges(); // No need to add this line if you have it in "beforeEach" block
const de = fixture.debugElement.query(By.css('.new-test-order-icd10-code-selection-modal.component'));
const element = de.nativeElement;
expect(element.textContent).toContain(component.title);
);
Update
For testing ng-template
you'll have to do it differently:
app.component.html
<div id="title">
title
</div>
<ng-template #content
let-modal
id="ng-modal">
<div class="modal-header dark-modal">
Header
</div>
<div class="justify-content-center flex-column flex-md-row list-inline">
Body
</div>
</ng-template>
app.component.ts
import Component, ViewChild, TemplateRef from '@angular/core';
@Component(
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
)
export class AppComponent
title = 'AngularProj';
@ViewChild('content') modalRef: TemplateRef<any>;
You need to write spec
file with slightly different way:
app.component.spec.ts
import TestBed, async, ComponentFixture from '@angular/core/testing';
import AppComponent from './app.component';
import ViewChild, Component, OnInit, AfterContentInit, TemplateRef from '@angular/core';
import By from '@angular/platform-browser';
@Component(
template: `
<ng-container *ngTemplateOutlet="modal"> </ng-container>
<app-root></app-root>
`,
)
class WrapperComponent implements AfterContentInit
@ViewChild(AppComponent) appComponentRef: AppComponent;
modal: TemplateRef<any>;
ngAfterContentInit()
this.modal = this.appComponentRef.modalRef;
describe('AppComponent', () =>
let app: AppComponent;
let fixture: ComponentFixture<WrapperComponent>;
beforeEach(async(() =>
TestBed.configureTestingModule(
declarations: [WrapperComponent, AppComponent],
).compileComponents();
));
beforeEach(() =>
fixture = TestBed.createComponent(WrapperComponent);
const wrapperComponent = fixture.debugElement.componentInstance;
app = wrapperComponent.appComponentRef;
fixture.detectChanges();
);
it('should create the app', async(() =>
expect(app).toBeDefined();
));
it('should have title in HtmL ', async(() =>
const titleText = (fixture.debugElement.nativeElement.querySelector('#title').innerText);
expect(titleText).toBe('AngularProj');
));
it('should have Header in HtmL ', async(() =>
const headerText = (fixture.debugElement.queryAll(By.css('.modal-header.dark-modal'))[0].nativeElement.innerText);
expect(headerText).toBe('Header');
));
);
- As you can see, I wrapped the
app-root
with a sample testing component (WrapperComponent
). - Since,
app-root
hasng-template
, so it won't render on it's own. This creates a tricky situation as we need to render this part of theapp.component
. - Expose
ng-template
by creating@ViewChild('content') modalRef: TemplateRef<any>;
and then using it to render insideWrapperComponent
.
I know it seems like a hack but over all the articles I went through, that's how we can achieve this.
add a comment |
My suggestion is to remove
de = fixture.debugElement.query(By.css('.new-test-order-icd10-code-selection-modal.component'));
from beforeEach
block. Please note that, you are trying to get this value before fixture.detectChanges();
, so I think it's not a good approach. You must make sure that you get the HTML values after all the angular changes are complete. Try:
it('Should have a title', () =>
fixture.detectChanges(); // No need to add this line if you have it in "beforeEach" block
const de = fixture.debugElement.query(By.css('.new-test-order-icd10-code-selection-modal.component'));
const element = de.nativeElement;
expect(element.textContent).toContain(component.title);
);
Update
For testing ng-template
you'll have to do it differently:
app.component.html
<div id="title">
title
</div>
<ng-template #content
let-modal
id="ng-modal">
<div class="modal-header dark-modal">
Header
</div>
<div class="justify-content-center flex-column flex-md-row list-inline">
Body
</div>
</ng-template>
app.component.ts
import Component, ViewChild, TemplateRef from '@angular/core';
@Component(
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
)
export class AppComponent
title = 'AngularProj';
@ViewChild('content') modalRef: TemplateRef<any>;
You need to write spec
file with slightly different way:
app.component.spec.ts
import TestBed, async, ComponentFixture from '@angular/core/testing';
import AppComponent from './app.component';
import ViewChild, Component, OnInit, AfterContentInit, TemplateRef from '@angular/core';
import By from '@angular/platform-browser';
@Component(
template: `
<ng-container *ngTemplateOutlet="modal"> </ng-container>
<app-root></app-root>
`,
)
class WrapperComponent implements AfterContentInit
@ViewChild(AppComponent) appComponentRef: AppComponent;
modal: TemplateRef<any>;
ngAfterContentInit()
this.modal = this.appComponentRef.modalRef;
describe('AppComponent', () =>
let app: AppComponent;
let fixture: ComponentFixture<WrapperComponent>;
beforeEach(async(() =>
TestBed.configureTestingModule(
declarations: [WrapperComponent, AppComponent],
).compileComponents();
));
beforeEach(() =>
fixture = TestBed.createComponent(WrapperComponent);
const wrapperComponent = fixture.debugElement.componentInstance;
app = wrapperComponent.appComponentRef;
fixture.detectChanges();
);
it('should create the app', async(() =>
expect(app).toBeDefined();
));
it('should have title in HtmL ', async(() =>
const titleText = (fixture.debugElement.nativeElement.querySelector('#title').innerText);
expect(titleText).toBe('AngularProj');
));
it('should have Header in HtmL ', async(() =>
const headerText = (fixture.debugElement.queryAll(By.css('.modal-header.dark-modal'))[0].nativeElement.innerText);
expect(headerText).toBe('Header');
));
);
- As you can see, I wrapped the
app-root
with a sample testing component (WrapperComponent
). - Since,
app-root
hasng-template
, so it won't render on it's own. This creates a tricky situation as we need to render this part of theapp.component
. - Expose
ng-template
by creating@ViewChild('content') modalRef: TemplateRef<any>;
and then using it to render insideWrapperComponent
.
I know it seems like a hack but over all the articles I went through, that's how we can achieve this.
add a comment |
My suggestion is to remove
de = fixture.debugElement.query(By.css('.new-test-order-icd10-code-selection-modal.component'));
from beforeEach
block. Please note that, you are trying to get this value before fixture.detectChanges();
, so I think it's not a good approach. You must make sure that you get the HTML values after all the angular changes are complete. Try:
it('Should have a title', () =>
fixture.detectChanges(); // No need to add this line if you have it in "beforeEach" block
const de = fixture.debugElement.query(By.css('.new-test-order-icd10-code-selection-modal.component'));
const element = de.nativeElement;
expect(element.textContent).toContain(component.title);
);
Update
For testing ng-template
you'll have to do it differently:
app.component.html
<div id="title">
title
</div>
<ng-template #content
let-modal
id="ng-modal">
<div class="modal-header dark-modal">
Header
</div>
<div class="justify-content-center flex-column flex-md-row list-inline">
Body
</div>
</ng-template>
app.component.ts
import Component, ViewChild, TemplateRef from '@angular/core';
@Component(
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
)
export class AppComponent
title = 'AngularProj';
@ViewChild('content') modalRef: TemplateRef<any>;
You need to write spec
file with slightly different way:
app.component.spec.ts
import TestBed, async, ComponentFixture from '@angular/core/testing';
import AppComponent from './app.component';
import ViewChild, Component, OnInit, AfterContentInit, TemplateRef from '@angular/core';
import By from '@angular/platform-browser';
@Component(
template: `
<ng-container *ngTemplateOutlet="modal"> </ng-container>
<app-root></app-root>
`,
)
class WrapperComponent implements AfterContentInit
@ViewChild(AppComponent) appComponentRef: AppComponent;
modal: TemplateRef<any>;
ngAfterContentInit()
this.modal = this.appComponentRef.modalRef;
describe('AppComponent', () =>
let app: AppComponent;
let fixture: ComponentFixture<WrapperComponent>;
beforeEach(async(() =>
TestBed.configureTestingModule(
declarations: [WrapperComponent, AppComponent],
).compileComponents();
));
beforeEach(() =>
fixture = TestBed.createComponent(WrapperComponent);
const wrapperComponent = fixture.debugElement.componentInstance;
app = wrapperComponent.appComponentRef;
fixture.detectChanges();
);
it('should create the app', async(() =>
expect(app).toBeDefined();
));
it('should have title in HtmL ', async(() =>
const titleText = (fixture.debugElement.nativeElement.querySelector('#title').innerText);
expect(titleText).toBe('AngularProj');
));
it('should have Header in HtmL ', async(() =>
const headerText = (fixture.debugElement.queryAll(By.css('.modal-header.dark-modal'))[0].nativeElement.innerText);
expect(headerText).toBe('Header');
));
);
- As you can see, I wrapped the
app-root
with a sample testing component (WrapperComponent
). - Since,
app-root
hasng-template
, so it won't render on it's own. This creates a tricky situation as we need to render this part of theapp.component
. - Expose
ng-template
by creating@ViewChild('content') modalRef: TemplateRef<any>;
and then using it to render insideWrapperComponent
.
I know it seems like a hack but over all the articles I went through, that's how we can achieve this.
My suggestion is to remove
de = fixture.debugElement.query(By.css('.new-test-order-icd10-code-selection-modal.component'));
from beforeEach
block. Please note that, you are trying to get this value before fixture.detectChanges();
, so I think it's not a good approach. You must make sure that you get the HTML values after all the angular changes are complete. Try:
it('Should have a title', () =>
fixture.detectChanges(); // No need to add this line if you have it in "beforeEach" block
const de = fixture.debugElement.query(By.css('.new-test-order-icd10-code-selection-modal.component'));
const element = de.nativeElement;
expect(element.textContent).toContain(component.title);
);
Update
For testing ng-template
you'll have to do it differently:
app.component.html
<div id="title">
title
</div>
<ng-template #content
let-modal
id="ng-modal">
<div class="modal-header dark-modal">
Header
</div>
<div class="justify-content-center flex-column flex-md-row list-inline">
Body
</div>
</ng-template>
app.component.ts
import Component, ViewChild, TemplateRef from '@angular/core';
@Component(
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
)
export class AppComponent
title = 'AngularProj';
@ViewChild('content') modalRef: TemplateRef<any>;
You need to write spec
file with slightly different way:
app.component.spec.ts
import TestBed, async, ComponentFixture from '@angular/core/testing';
import AppComponent from './app.component';
import ViewChild, Component, OnInit, AfterContentInit, TemplateRef from '@angular/core';
import By from '@angular/platform-browser';
@Component(
template: `
<ng-container *ngTemplateOutlet="modal"> </ng-container>
<app-root></app-root>
`,
)
class WrapperComponent implements AfterContentInit
@ViewChild(AppComponent) appComponentRef: AppComponent;
modal: TemplateRef<any>;
ngAfterContentInit()
this.modal = this.appComponentRef.modalRef;
describe('AppComponent', () =>
let app: AppComponent;
let fixture: ComponentFixture<WrapperComponent>;
beforeEach(async(() =>
TestBed.configureTestingModule(
declarations: [WrapperComponent, AppComponent],
).compileComponents();
));
beforeEach(() =>
fixture = TestBed.createComponent(WrapperComponent);
const wrapperComponent = fixture.debugElement.componentInstance;
app = wrapperComponent.appComponentRef;
fixture.detectChanges();
);
it('should create the app', async(() =>
expect(app).toBeDefined();
));
it('should have title in HtmL ', async(() =>
const titleText = (fixture.debugElement.nativeElement.querySelector('#title').innerText);
expect(titleText).toBe('AngularProj');
));
it('should have Header in HtmL ', async(() =>
const headerText = (fixture.debugElement.queryAll(By.css('.modal-header.dark-modal'))[0].nativeElement.innerText);
expect(headerText).toBe('Header');
));
);
- As you can see, I wrapped the
app-root
with a sample testing component (WrapperComponent
). - Since,
app-root
hasng-template
, so it won't render on it's own. This creates a tricky situation as we need to render this part of theapp.component
. - Expose
ng-template
by creating@ViewChild('content') modalRef: TemplateRef<any>;
and then using it to render insideWrapperComponent
.
I know it seems like a hack but over all the articles I went through, that's how we can achieve this.
edited May 1 at 10:01
answered Mar 28 at 10:54
Shashank VivekShashank Vivek
7,3463 gold badges27 silver badges67 bronze badges
7,3463 gold badges27 silver badges67 bronze badges
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55392057%2fkarma-showing-this-error-typeerror-cannot-read-property-textcontent-of-undefi%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
It is not finding element.textContent because your thread(async) running before having any values in element.textContent
– atishr
Mar 28 at 7:26
@ShashankVivek i tried but its still not working may be its because of my html file i closed it in ng-template ?
– Salman Ahmad
Mar 29 at 5:40
@SalmanAhmad : what is the condition to render
#icd10codes
on html ?? Please update entire html code in the post andnot
in the comments :) .ng-template
is not rendered by default. So, your test case wont find it– Shashank Vivek
Mar 29 at 5:58
@ShashankVivek Thanks for taking the time i have updated it with my html code :)
– Salman Ahmad
Mar 29 at 6:07
1
@ShashankVivek Yes this is the full html file. Actually what is happening here is this components ng-template only gets true when you click on this components field on its parent component. So when i am testing its not actually loading the component thats the reason now after trying your described method of writing test its showing this error Expected undefined to contain Please Select ICD-10 Codes i guess i would have to implement it differently .. I appreciate you taking the time and look into this you helped me alot Thanks :)
– Salman Ahmad
Mar 29 at 12:06