2016-03-16 92 views
0

我通过克隆angular2-seed创建了一个新的Angular 2项目。我能够创建一个SearchComponent及其关联的模板,并在我的浏览器中使用它。为Angular 2组件运行Jasmine测试时出错(angular2-seed)

这里是我的search.component.ts

import {Component} from 'angular2/core'; 
import {CORE_DIRECTIVES, FORM_DIRECTIVES} from 'angular2/common'; 
import {ROUTER_DIRECTIVES, RouteParams} from 'angular2/router'; 
import {Person, SearchService} from '../../shared/services/search.service'; 

@Component({ 
    selector: 'sd-search', 
    moduleId: module.id, 
    templateUrl: './search.component.html', 
    directives: [FORM_DIRECTIVES, CORE_DIRECTIVES, ROUTER_DIRECTIVES] 
}) 
export class SearchComponent { 
    loading: boolean; 
    query: string; 
    searchResults: Array<Person>; 

    constructor(public searchService: SearchService, params: RouteParams) { 
    if (params.get('term')) { 
     this.query = decodeURIComponent(params.get('term')); 
     this.search(); 
    } 
    } 

    search(): void { 
    this.searchService.search(this.query).subscribe(
     data => {this.searchResults = data;}, 
     error => console.log(error) 
    ); 
    } 
} 

这里是我的search.component.html

<h2>Search</h2> 
<form> 
    <input type="search" [(ngModel)]="query" (keyup.enter)="search()"> 
    <button type="button" (click)="search()">Search</button> 
</form> 
<div *ngIf="loading">loading...</div> 

<table *ngIf="searchResults"> 
    <thead> 
    <tr> 
    <th>Name</th> 
    <th>Phone</th> 
    <th>Address</th> 
    </tr> 
    </thead> 
    <tbody> 
    <tr *ngFor="#person of searchResults; #i=index"> 
    <td>{{person.name}}</td> 
    <td>{{person.phone}}</td> 
    <td>{{person.address.street}}<br/> 
     {{person.address.city}}, {{person.address.state}} {{person.address.zip}} 
    </td> 
    </tr> 
    </tbody> 
</table> 

现在我试图创建单元测试,以验证该组件的工作原理。据我所知,angular2-seed要求您有一个围绕根describeexport main function()。见https://github.com/mgechev/angular2-seed/blob/master/test-main.js#L50

下面是search.component.spec.ts我试图让工作:

import { 
    it, 
    describe, 
    expect, 
    injectAsync, 
    beforeEachProviders, 
    TestComponentBuilder, 
} from 'angular2/testing'; 

import {MockRouterProvider} from '../../shared/services/mocks/routes'; 
import {MockSearchService} from '../../shared/services/mocks/search.service'; 

import {SearchComponent} from './search.component'; 

export function main() { 
    describe('Search component',() => { 
    var mockSearchService:MockSearchService; 
    var mockRouterProvider:MockRouterProvider; 

    beforeEachProviders(() => { 
     mockSearchService = new MockSearchService(); 
     mockRouterProvider = new MockRouterProvider(); 

     return [ 
     mockSearchService.getProviders(), mockRouterProvider.getProviders() 
     ]; 
    }); 

    it('should search when a term is set and search() is called', injectAsync([TestComponentBuilder], (tcb) => { 
     return tcb.createAsync(SearchComponent).then((fixture) => { 
     let searchComponent = fixture.debugElement.children[0].componentInstance; 
     searchComponent.query = 'M'; 
     searchComponent.search(); 
     expect(mockSearchService.searchSpy).toHaveBeenCalledWith('M'); 
     }); 
    })); 

    it('should search automatically when a term is on the URL', injectAsync([TestComponentBuilder], (tcb) => { 
     mockRouterProvider.setRouteParam('term', 'peyton'); 
     return tcb.createAsync(SearchComponent).then((fixture) => { 
     fixture.detectChanges(); 
     expect(mockSearchService.searchSpy).toHaveBeenCalledWith('peyton'); 
     }); 
    })); 
    }); 
} 

模拟*类基于例子我在ng-book2找到。

奇怪的是我在我的项目中运行npm test时看到的错误。

PhantomJS 2.1.1 (Mac OS X 0.0.0) ERROR: Error{stack: null, originalErr: ReferenceError{stack: ' 
eval code 
[email protected][native code] 
[email protected]://localhost:9877/base/node_modules/systemjs/dist/system.src.js?4db5a6e7fcabd81638571091a65db6438de248ef:1419:16 
[email protected]://localhost:9877/base/node_modules/systemjs/dist/system.src.js?4db5a6e7fcabd81638571091a65db6438de248ef:3824:22 
[email protected]://localhost:9877/base/node_modules/systemjs/dist/system.src.js?4db5a6e7fcabd81638571091a65db6438de248ef:3153:36 
[email protected]://localhost:9877/base/node_modules/systemjs/dist/system.src.js?4db5a6e7fcabd81638571091a65db6438de248ef:3121:26 
http://localhost:9877/base/node_modules/systemjs/dist/system.src.js?4db5a6e7fcabd81638571091a65db6438de248ef:3157:25 
[email protected]://localhost:9877/base/node_modules/systemjs/dist/system.src.js?4db5a6e7fcabd81638571091a65db6438de248ef:3791:34 

eval code 
[email protected][native code] 
[email protected]://localhost:9877/base/node_modules/systemjs/dist/system.src.js?4db5a6e7fcabd81638571091a65db6438de248ef:1419:16 
[email protected]://localhost:9877/base/node_modules/systemjs/dist/system.src.js?4db5a6e7fcabd81638571091a65db6438de248ef:3824:22 
[email protected]://localhost:9877/base/node_modules/systemjs/dist/system.src.js?4db5a6e7fcabd81638571091a65db6438de248ef:3153:36 
[email protected]://localhost:9877/base/node_modules/systemjs/dist/system.src.js?4db5a6e7fcabd81638571091a65db6438de248ef:2996:28 
[email protected]://localhost:9877/base/node_modules/systemjs/dist/system.src.js?4db5a6e7fcabd81638571091a65db6438de248ef:3333:17 
[email protected]://localhost:9877/base/node_modules/systemjs/dist/system.src.js?4db5a6e7fcabd81638571091a65db6438de248ef:727:32 
[email protected]://localhost:9877/base/node_modules/systemjs/dist/system.src.js?4db5a6e7fcabd81638571091a65db6438de248ef:929:36 
[email protected]://localhost:9877/base/node_modules/systemjs/dist/system.src.js?4db5a6e7fcabd81638571091a65db6438de248ef:581:11 
[email protected]://localhost:9877/base/node_modules/systemjs/dist/system.src.js?4db5a6e7fcabd81638571091a65db6438de248ef:629:24 
http://localhost:9877/base/node_modules/systemjs/dist/system.src.js?4db5a6e7fcabd81638571091a65db6438de248ef:441:30 
[email protected]://localhost:9877/base/node_modules/zone.js/dist/zone-microtask.js?572d97c64312c5d52018e95b072a38b5443b057e:1217:29 
[email protected]://localhost:9877/base/node_modules/zone.js/dist/zone-microtask.js?572d97c64312c5d52018e95b072a38b5443b057e:1194:29 
[email protected]://localhost:9877/base/node_modules/zone.js/dist/zone-microtask.js?572d97c64312c5d52018e95b072a38b5443b057e:442:25 
[email protected]://localhost:9877/base/node_modules/zone.js/dist/zone-microtask.js?572d97c64312c5d52018e95b072a38b5443b057e:454:53 
[email protected]://localhost:9877/base/node_modules/zone.js/dist/zone-microtask.js?572d97c64312c5d52018e95b072a38b5443b057e:425:53 
http://localhost:9877/base/node_modules/zone.js/dist/zone-microtask.js?572d97c64312c5d52018e95b072a38b5443b057e:97:12 
[email protected]://localhost:9877/base/node_modules/zone.js/dist/zone-microtask.js?572d97c64312c5d52018e95b072a38b5443b057e:1217:29 
[email protected]://localhost:9877/base/node_modules/zone.js/dist/zone-microtask.js?572d97c64312c5d52018e95b072a38b5443b057e:1194:29 
[email protected]://localhost:9877/base/node_modules/zone.js/dist/zone-microtask.js?572d97c64312c5d52018e95b072a38b5443b057e:236:18', line: 9}, line: 752, sourceURL: 'http://localhost:9877/base/node_modules/systemjs/dist/system.src.js?4db5a6e7fcabd81638571091a65db6438de248ef'} 
ERROR: Error{originalErr: ReferenceError{}} 

任何想法我做错了什么?

+0

没关系,我想通了。我的'MockSearchService'缺少导入和一个构造函数来初始化间谍。将其从https://gist.github.com/mraible/4af1fc8902f8c19e77c2更改为https://gist.github.com/mraible/573c892bbd9d4d799dbd,使我得到正确的错误消息。 –

回答

0

我的MockSearchService缺少导入和一个构造函数来初始化间谍。

export class MockSearchService extends SpyObject { 
    getAllSpy; 
    getByIdSpy; 
    searchSpy; 
    saveSpy; 
    mockObservable; 
    fakeResponse; 

    subscribe(callback) { 
    callback(this.fakeResponse); 
    } 

    setResponse(json: any): void { 
    this.fakeResponse = json; 
    } 

    getProviders(): Array<any> { 
    return [provide(SearchService, {useValue: this})]; 
    } 
} 

到:从改变它

import {provide} from 'angular2/core'; 
import {SpyObject} from 'angular2/testing_internal'; 

import {SearchService} from '../search.service'; 

export class MockSearchService extends SpyObject { 
    getAllSpy; 
    getByIdSpy; 
    searchSpy; 
    saveSpy; 
    fakeResponse; 

    constructor() { 
    super(SearchService); 

    this.fakeResponse = null; 
    this.getAllSpy = this.spy('getAll').andReturn(this); 
    this.getByIdSpy = this.spy('get').andReturn(this); 
    this.searchSpy = this.spy('search').andReturn(this); 
    this.saveSpy = this.spy('save').andReturn(this); 
    } 

    subscribe(callback) { 
    callback(this.fakeResponse); 
    } 

    setResponse(json: any): void { 
    this.fakeResponse = json; 
    } 

    getProviders(): Array<any> { 
    return [provide(SearchService, {useValue: this})]; 
    } 
} 

使我得到正确的错误消息。