首页 文章

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

提问于
浏览
0

我通过克隆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}}
{{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

    我的MockSearchService缺少导入和初始化 Spy 的构造函数 . 改变它:

    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})];
      }
    }
    

    导致我得到正确的错误消息 .

相关问题