运行Angular 2 Component(angular2-seed)的Jasmine测试时出错

时间:2016-03-16 03:34:12

标签: jasmine angular

我通过克隆angular2-seed创建了一个新的Angular 2项目。我能够创建一个SearchComponent及其相关模板,并在我的浏览器中运行它。

这是我的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要求你有export main function()缠绕根describe。见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');
      });
    }));
  });
}

Mock *类基于我在ng-book2中找到的示例。

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

PhantomJS 2.1.1 (Mac OS X 0.0.0) ERROR: Error{stack: null, originalErr: ReferenceError{stack: '
eval code
eval@[native code]
__exec@http://localhost:9877/base/node_modules/systemjs/dist/system.src.js?4db5a6e7fcabd81638571091a65db6438de248ef:1419:16
execute@http://localhost:9877/base/node_modules/systemjs/dist/system.src.js?4db5a6e7fcabd81638571091a65db6438de248ef:3824:22
linkDynamicModule@http://localhost:9877/base/node_modules/systemjs/dist/system.src.js?4db5a6e7fcabd81638571091a65db6438de248ef:3153:36
getModule@http://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
require@http://localhost:9877/base/node_modules/systemjs/dist/system.src.js?4db5a6e7fcabd81638571091a65db6438de248ef:3791:34

eval code
eval@[native code]
__exec@http://localhost:9877/base/node_modules/systemjs/dist/system.src.js?4db5a6e7fcabd81638571091a65db6438de248ef:1419:16
execute@http://localhost:9877/base/node_modules/systemjs/dist/system.src.js?4db5a6e7fcabd81638571091a65db6438de248ef:3824:22
linkDynamicModule@http://localhost:9877/base/node_modules/systemjs/dist/system.src.js?4db5a6e7fcabd81638571091a65db6438de248ef:3153:36
link@http://localhost:9877/base/node_modules/systemjs/dist/system.src.js?4db5a6e7fcabd81638571091a65db6438de248ef:2996:28
execute@http://localhost:9877/base/node_modules/systemjs/dist/system.src.js?4db5a6e7fcabd81638571091a65db6438de248ef:3333:17
doDynamicExecute@http://localhost:9877/base/node_modules/systemjs/dist/system.src.js?4db5a6e7fcabd81638571091a65db6438de248ef:727:32
link@http://localhost:9877/base/node_modules/systemjs/dist/system.src.js?4db5a6e7fcabd81638571091a65db6438de248ef:929:36
doLink@http://localhost:9877/base/node_modules/systemjs/dist/system.src.js?4db5a6e7fcabd81638571091a65db6438de248ef:581:11
updateLinkSetOnLoad@http://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
run@http://localhost:9877/base/node_modules/zone.js/dist/zone-microtask.js?572d97c64312c5d52018e95b072a38b5443b057e:1217:29
zoneBoundFn@http://localhost:9877/base/node_modules/zone.js/dist/zone-microtask.js?572d97c64312c5d52018e95b072a38b5443b057e:1194:29
lib$es6$promise$$internal$$tryCatch@http://localhost:9877/base/node_modules/zone.js/dist/zone-microtask.js?572d97c64312c5d52018e95b072a38b5443b057e:442:25
lib$es6$promise$$internal$$invokeCallback@http://localhost:9877/base/node_modules/zone.js/dist/zone-microtask.js?572d97c64312c5d52018e95b072a38b5443b057e:454:53
lib$es6$promise$$internal$$publish@http://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
run@http://localhost:9877/base/node_modules/zone.js/dist/zone-microtask.js?572d97c64312c5d52018e95b072a38b5443b057e:1217:29
zoneBoundFn@http://localhost:9877/base/node_modules/zone.js/dist/zone-microtask.js?572d97c64312c5d52018e95b072a38b5443b057e:1194:29
lib$es6$promise$asap$$flush@http://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{}}

知道我做错了什么吗?

1 个答案:

答案 0 :(得分: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})];
  }
}

导致我收到正确的错误消息。