如何在AngularJS2"最终"?中单元测试组件?

时间:2016-09-25 21:52:43

标签: javascript unit-testing angular typescript components

我目前正在尝试为非常简单的AngularJs2组件编写单元测试。

这是打字稿:

// 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;
}

这是模板:

<!-- cell.component.html -->
<div class="ticTacToe--board-cell ticTacToe--board-cell--{{cell.background}}">
    <div class="ticTacToe--board-cell--{{cell.displayMarker()}}">{{cell.displayMarker()}}</div>
</div>

这是我目前的测试:

// 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');
            });
        }));
    });

这失败了:

  

Chrome 49.0.2623(Windows XP 0.0.0)CellComponent应呈现一个单元格   FAILED1] [1]失败:未捕获(承诺):错误:错误   app / cell.component.html:1:9由:self.context.cell.displayMarker引起   不是函数[1]错误:未捕获(在承诺中):错误:错误   在app / cell.component.html:1:9引起的:   self.context.cell.displayMarker不是函数

但是displayMarker是我的Cell类中的一个函数:

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;

...并且在手动测试时(而不是通过Karma / Jasmine),这样可以正常工作。

任何想法如何让我的单元测试工作?

1 个答案:

答案 0 :(得分:3)

一些错误。

  1. export class CellComponent {
        @Input()
        cell = Cell;  <===========
    }
    

    您要将Cell 功能分配给cell。它在手动测试时起作用,因为类型信息消失了,你可以为它分配任何东西。所以,当你向它传递一个实际的Cell实例时,它就没问题了。但应将其更改为使用 type 语法

    @Input() cell: Cell;
    
  2. const fixture = TestBed.createComponent(CellComponent);
    const componentUnderTest = fixture.nativeElement;
    

    fixture.nativeElement 没有为您提供测试中的组件,它会为您提供DOM元素。为什么你认为你可以做componentUnderTest.querySelectorAll

    您应该使用fixture.componentInstance来获取正在测试的组件。