Reputation: 2327
I'm currently trying to write a unit test for a very simple AngularJs2 component.
This is the Typescript:
// cell.component.ts
import { Component, Input } from '@angular/core';
import Cell from './cell';
@Component({
moduleId: module.id,
selector: 'cell',
templateUrl: 'cell.component.html',
styleUrls: ['cell.component.css']
})
export class CellComponent {
@Input()
cell = Cell;
}
This is the template:
<!-- cell.component.html -->
<div class="ticTacToe--board-cell ticTacToe--board-cell--{{cell.background}}">
<div class="ticTacToe--board-cell--{{cell.displayMarker()}}">{{cell.displayMarker()}}</div>
</div>
And here is my current test:
// cell.component.spec.ts
import { async, inject, TestBed } from '@angular/core/testing';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
import { ReflectiveInjector } from '@angular/core';
import { CellComponent } from './cell.component';
import Cell from './cell';
import Marker from './marker.enum';
//TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
describe('CellComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [CellComponent]
});
});
it ('should render a cell', async(() => {
TestBed.compileComponents().then(() => {
// Arrange
const fixture = TestBed.createComponent(CellComponent);
const componentUnderTest = fixture.nativeElement;
const testId = 1;
const testMarker = Marker.X;
const testCell = new Cell(1);
testCell['marker'] = testMarker;
// Act
componentUnderTest.cell = testCell;
// Assert
fixture.detectChanges();
expect(componentUnderTest.querySelectorAll('div.ticTacToe--board-cell').length).toBe(1);
expect(componentUnderTest.querySelectorAll('div.ticTacToe--board-cell--background').length).toBe(1);
expect(componentUnderTest.querySelectorAll('div.ticTacToe--board-cell--X').length).toBe(1);
expect(componentUnderTest.querySelectorAll('div.ticTacToe--board-cell--X')[0].innerText).toBe('X');
});
}));
});
This fails with:
Chrome 49.0.2623 (Windows XP 0.0.0) CellComponent should render a cell FAILED1] [1] Failed: Uncaught (in promise): Error: Error in app/cell.component.html:1:9 caused by: self.context.cell.displayMarker is not a function [1] Error: Uncaught (in promise): Error: Error in app/cell.component.html:1:9 caused by: self.context.cell.displayMarker is not a function
But displayMarker is a function in my Cell class:
import Marker from './marker.enum';
export class Cell {
id: number;
private marker: Marker;
private background = 'background';
constructor(id: number) {
this.id = id;
}
displayMarker() {
return Marker[this.marker];
}
getMarker() {
return this.marker;
}
setMarker(marker: Marker) {
if (!this.marker) {
this.marker = marker;
}
}
declareWinner() {
this.background = 'winner';
}
isEmpty() {
return this.marker === undefined;
}
}
export default Cell;
... and when tested manually (instead of through Karma/Jasmine) this works fine.
Any ideas how I can make my unit test work?
Upvotes: 2
Views: 105
Reputation: 209002
A couple mistakes.
export class CellComponent {
@Input()
cell = Cell; <===========
}
You're assigning the Cell
function to cell
. It works at when manually testing because type information is gone, and you can assign whatever to it. So when you do pass an actual Cell
instance to it, then it is fine. But it should be changed to use the type syntax
@Input() cell: Cell;
const fixture = TestBed.createComponent(CellComponent);
const componentUnderTest = fixture.nativeElement;
fixture.nativeElement
does not give you the component under test, it give you the DOM element. Why do yo think you can do componentUnderTest.querySelectorAll
?
You should be instead be using fixture.componentInstance
to get the component under test.
Upvotes: 3