Aousaf Rashid
Aousaf Rashid

Reputation: 5738

Jasmine Angular component is undefined

I am a bit new to Angular 7 and totally new to it's unit testing framework Jasmine

So i have been following the docs of Jasmine and also some tutorials. I have component called TestTableComponent. Now the component is a bit hard-coded. Anyways, i think the issue i'm facing hardly has anything to do with the component itself, so i am not including the component's code here.

I created a testing class, inside test-table.component.spec.ts. The code is as follows :

// Required Imports have been made. Not including as unnecessary.

describe('TestTableComponent',  async() => 
{
let component: TestTableComponent;
let fixture: ComponentFixture<TestTableComponent>;
let de: DebugElement;


beforeEach(async(() => 
{
    TestBed.configureTestingModule({declarations:[TestTableComponent],
    imports: [ReactiveFormsModule]}).compileComponents();
}));
beforeEach(() =>
{
    fixture = TestBed.createComponent(TestTableComponent);
    component = fixture.componentInstance;

    de = fixture.debugElement;
})


it('should check if data is returned by the API')
{

    const result = await component.GetEmployees;
    expect(result).toBeDefined();
}
});

The issue here is that, when i execute ng test, it seems to run the test based on this class. In the console of the browser, i get one error(for which, Jasmine says 1 component is pending) as follows :

Cannot read property GetEmployees of undefined.

Now, this clearly means that TestTableComponent is never initialized. I am just wondering why? Is beforeEach not being executed? If it is, then why is component undefined ?

UPDATE : Including the component's code

Test-table.component.ts

import { AfterViewInit, Component, OnInit, ViewChild, Inject } from '@angular/core';
import { MatPaginator, MatSort, MatTable, MatTableDataSource, MatDialogRef, Sort, ShowOnDirtyErrorStateMatcher } from '@angular/material';
import { MatDialog } from '@angular/material/dialog';
import { TestTableItem } from './test-table-datasource';
import { HttpClient, HttpParams } from '@angular/common/http';
import { UpdateModalDialogComponent } from '../update-modal-dialog/update-modal-dialog.component';
import { MessagePopUpComponent } from '../message-pop-up/message-pop-up.component';
@Component({
selector: 'app-test-table',
templateUrl: './test-table.component.html',
styleUrls: ['./test-table.component.css']
})
export class TestTableComponent implements AfterViewInit, OnInit {
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator;
@ViewChild(MatSort, { static: false }) sort: MatSort;
@ViewChild(MatTable, { static: false }) table: MatTable<TestTableItem>;
private myCollection: TestTableItem[] = [];

dataSource = new MatTableDataSource(this.myCollection);// Observable<TestTableItem>;
/** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */
displayedColumns = ['id', 'fname', 'salary', 'age', 'image', 'actions'];
constructor(private http: HttpClient, private dialog:MatDialog) { }


ngOnInit() {

   this.GetAllEmployees();
 }

async GetAllEmployees()
{
 this.dataSource = await this.GetEmployees();
}
public async GetEmployees()
{
 this.myCollection = await this.http.get<TestTableItem[]>('http://localhost:22371/api/employee/GetEmployees/').toPromise();
return new MatTableDataSource(this.myCollection);

}

Please note that i am not including all the functions inside the class, as that would make this post unnecessarily big!

Upvotes: 1

Views: 6931

Answers (2)

Ethan Vu
Ethan Vu

Reputation: 2987

You writing the wrong it() function syntax, it should take first parameter is the string description and second parameter is the callback that implement your test:

it('should check if data is returned by the API', async(() =>{
    fixture.detectChanges();
    const result = component.GetEmployees();
    fixture.whenStable().then(()=>{
      expect(result).toBeDefined();
    })
}))

Upvotes: 1

Erbsenkoenig
Erbsenkoenig

Reputation: 1659

Besides the wrong it() syntax @Ethan mentioned. You need to set either NO_ERRORS_SCHEMA to your TestBed or you need to include missing dependencies into your TestBed.

I personally prefer the NO_ERRORS_SCHEMA approach since imho a unit test does not need to test whether some third party library works right, but that is up to you. This approach is usually referred to as shallow testing a component

The schema is set like this:

TestBed.configureTestingModule({
    declarations:[TestTableComponent],
    imports: [ReactiveFormsModule],
    schemas: [NO_ERRORS_SCHEMA]

}).compileComponents();

Please have a look at the official documentation on nested component tests

Upvotes: 1

Related Questions