错误:必须定义令牌!使用Angular 2 RC5进行测试时

时间:2016-08-17 15:09:54

标签: angular jasmine angular2-testing

早在2016年6月,我写了一篇关于如何测试Angular 2应用程序的文章。我使用angular2-seed作为起点。

https://raibledesigns.com/rd/entry/testing_angular_2_0_rc1

我决定使用Angular CLI(来自其主分支)重写本教程,该角色使用Angular 2 RC5。我从我的一次测试中看到了一个奇怪的错误。

Error: Token must be defined!
    at new BaseException (/Users/mraible/ng2-demo/src/test.ts:1940:23 <- webpack:///Users/mraible/ng2-demo/~/@angular/core/src/facade/exceptions.js:27:0)
    at new ReflectiveKey (/Users/mraible/ng2-demo/src/test.ts:27600:19 <- webpack:///Users/mraible/ng2-demo/~/@angular/core/src/di/reflective_key.js:36:0)
    at KeyRegistry.get (/Users/mraible/ng2-demo/src/test.ts:27641:22 <- webpack:///Users/mraible/ng2-demo/~/@angular/core/src/di/reflective_key.js:77:0)
    at Function.ReflectiveKey.get (/Users/mraible/ng2-demo/src/test.ts:27615:35 <- webpack:///Users/mraible/ng2-demo/~/@angular/core/src/di/reflective_key.js:51:0)
    at ReflectiveInjector_.get (/Users/mraible/ng2-demo/src/test.ts:58418:62 <- webpack:///Users/mraible/ng2-demo/~/@angular/core/src/di/reflective_injector.js:586:0)
    at NgModuleInjector.get (/Users/mraible/ng2-demo/src/test.ts:40942:52 <- webpack:///Users/mraible/ng2-demo/~/@angular/core/src/linker/ng_module_factory.js:98:0)
    at TestBed.get (/Users/mraible/ng2-demo/src/test.ts:11910:47 <- webpack:///Users/mraible/ng2-demo/~/@angular/core/testing/test_bed.js:269:0)
    at /Users/mraible/ng2-demo/src/test.ts:11916:61 <- webpack:///Users/mraible/ng2-demo/~/@angular/core/testing/test_bed.js:275:46
    at Array.map (native)
    at TestBed.execute (/Users/mraible/ng2-demo/src/test.ts:11916:29 <- webpack:///Users/mraible/ng2-demo/~/@angular/core/testing/test_bed.js:275:0)

这是我的测试:

import { provide } from '@angular/core';
import { TestComponentBuilder } from '@angular/compiler/testing';

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

import { EditComponent } from './edit.component';
import { ActivatedRoute } from "@angular/router";
import { inject } from "@angular/core/testing/test_bed";

describe('Component: Edit', () => {
  var mockSearchService:MockSearchService;

  beforeEach(() => {
    mockSearchService = new MockSearchService();

    return [
      mockSearchService.getProviders(),
      provide(ActivatedRoute, { useValue: new MockActivatedRoute({ 'id': '1' }) })
    ];
  });

  it('should fetch a single record', inject([TestComponentBuilder], (tcb:TestComponentBuilder) => {
    return tcb.createAsync(EditComponent).then((fixture) => {
      let person = {name: 'Emmanuel Sanders', address: {city: 'Denver'}};
      mockSearchService.setResponse(person);

      fixture.detectChanges();
      // verify service was called
      expect(mockSearchService.getByIdSpy).toHaveBeenCalledWith(1);

      // verify data was set on component when initialized
      let editComponent = fixture.debugElement.componentInstance;
      expect(editComponent.editAddress.city).toBe('Denver');

      // verify HTML renders as expected
      var compiled = fixture.debugElement.nativeElement;
      expect(compiled.querySelector('h3')).toBe('Emmanuel Sanders');
    });
  }));
});

我已将此项目发布到GitHub,因此如果您愿意,可以重现此问题:https://github.com/mraible/ng2-demo

1 个答案:

答案 0 :(得分:1)

马特,我已经复制了我认为your working code的相关内容,以帮助任何可能在将来偶然发现这个问题的人。

您提到您的修复方法是从TestBed导入@angular/core/testing,我注意到您也遵循注入模拟服务的指导,其方式也反映在angular testing documentation and guidelines

我的修复有点不同;这是由于我在TestBed.configureTestingModule()方法中提供的其中一项服务的误解。

例如,在您的情况下,您实例化一个新的MockSearchService并将其作为providers传递到mockSearchService数组中,如下所示:{{1 }}。

就我而言,我传递了{provide: SearchService, useValue: mockSearchService} 类型(注意,实际类型,而不是实例),如下所示:MockSearchService(注意大小写)。 ..

...然后获得服务的实例,如下所示:{provide: SearchService, useValue: MockSearchService}

然而,在我的情况下,我错误拼写了我传入的mockSearchService = fixture.debugElement.injector.get(MockSearchService);值,这是一个无效的令牌传递给注入器getter。所以,我认为这个无效的令牌错误是由Karma引起的,或者是测试过程中涉及的其他工具之一,因为它试图访问或传入未定义的令牌。故事的道德,它可能与某个变量的误解有关。你的情况有点不同,但我几乎肯定它是以某种方式相关的:]。干杯!

您的工作代码

...injector.get(mockSearchService)