如何在 AngularJS2“final”中对组件进行单元测试?

Posted

技术标签:

【中文标题】如何在 AngularJS2“final”中对组件进行单元测试?【英文标题】:How can I unit test components in AngularJS2 "final"? 【发布时间】:2017-02-03 04:03:43 【问题描述】:

我目前正在尝试为一个非常简单的 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】:

几个错误。

    export class CellComponent 
        @Input()
        cell = Cell;  <===========
    
    

    您将Cell 函数 分配给cell。它在手动测试时起作用,因为类型信息已经消失,您可以为其分配任何内容。因此,当您确实将实际的 Cell 实例传递给它时,就可以了。但是应该改成使用type语法

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

    fixture.nativeElement 给你被测组件,它给你DOM元素。为什么你认为你可以做到componentUnderTest.querySelectorAll

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

【讨论】:

感谢您的反馈。将对此进行检查。 尝试根据您的反馈更改我的 CellComponent 类,但不幸的是最终结果完全相同。 :-(也就是说,当我重新启动游戏本身时,我注意到转译器正在考虑在至少需要 es2015 的规范文件中使用异步...我不知道这是否是一个单独的问题... 您解决了问题 2 吗?至于转译器的问题,我不确定 抱歉,当我发表最后一条评论时,我还没有醒来。我重新阅读并再次检查了我的代码,它现在可以工作了。 :-) 干杯!

以上是关于如何在 AngularJS2“final”中对组件进行单元测试?的主要内容,如果未能解决你的问题,请参考以下文章

angularjs2 学习笔记 服务

angularjs2 学习笔记 组件

angularjs2 学习笔记 组件

angularjs2 外部设置组件header的属性

迈向angularjs2系列:组件详解

angularjs2 简单使用起始篇